python 单例模式,一个类只能生成唯一的一个实例,重写__new__方法详解


单例:一个类只能生成唯一的一个实例

 

每个类只要被实例化了,他的私有属性 '_instance'就会被赋值,这样理解对吗

 

 

#方法1,实现__new__方法

 

#并在将一个类的实例绑定到类变量_instance上,

 

#如果cls._instance为None说明该类还没有实例化过,则实例化该类,并返回实例对象

 

#如果cls._instance不为None,直接返回已经实例化了的实例对象

 

cls._instance

 

#super(Singleton, cls)是object 的意思

 

#coding=utf-8

 

class Singleton(object):

 

    def __new__(cls, *args, **kw):

 

        if not hasattr(cls, '_instance'):

 

            orig = super(Singleton, cls)

 

            cls._instance = orig.__new__(cls, *args, **kw)

 

            #cls._instance = object.__new__(cls, *args, **kw)  #等价上一句

 

        return cls._instance

 

 

 

class MyClass(Singleton):

 

    a = 1

 

 

 

one = MyClass()

 

two = MyClass()

 

 

 

two.a = 3

 

print one.a

 

#3

 

#one和two完全相同,可以用id(), ==, is检测

 

print id(one)

 

#40579184

 

print id(two)

 

#40579184

 

print one == two

 

#True

 

print one is two

 

#True

 

c:\Python27\Scripts>python task_test.py

 

3

 

40579184

 

40579184

 

True

 

True

 

 

 

程序解释:

 

 

 

#coding=utf-8
class Singleton(object):
    def __new__(cls, *args, **kw):
        if not 判断此类是否存在类变量_instance“”
            如果不存在,则生成一个Singleton的实例
            并且赋值给类变量_instance
         
         下面返回类变量中保存的实例对象
         return cls._instance

 

 

 

#coding=utf-8
class Singleton(object):
    def __new__(cls, *args, **kw):
        #如果不存在类变量_instance,则执行if下的子句
        if not hasattr(cls, '_instance'):
            #下面两句,表示使用object.__new__方法生成了Singleton的一个实例

 

#super(Singleton, cls)是object 的意思
            orig = super(Singleton, cls)#这句参考下边的调用基类构造方法,没有后边的.__init…,

 

      #应该就是表示基类object,只不过是把类名赋值给orig了
            cls._instance = orig.__new__(cls, *args, **kw)#从下边可以看到改成

 

      #cls._instance = object.__new__(cls, *args, **kw),结果是一样的
        #返回类对象中保存的实例对象
        return cls._instance

 

‘’’

 

#调用基类构造方法例子

 

class C(A):

 

    def __init__(self):

 

        super(C,self).__init__()#调用基类构造方法

 

‘’’

 

c:\Python27\Scripts>python task_test.py

 

3

 

40403056

 

40403056

 

True

 

True

 

 

 

改成另一种调用基类__new__的方法:

 

#coding=utf-8

 

 

 

class Singleton(object):

 

    def __new__(cls,*args,**kw):

 

        if not hasattr(cls,'_instance'):

 

            #orig=super(Singleton,cls)

 

            cls._instance=object.__new__(cls,*args,**kw)

 

        return cls._instance

 

 

 

class MyClass(Singleton):

 

    a=1

 

 

 

one=MyClass()

 

two=MyClass()

 

 

 

two.a=3

 

 

 

print one.a

 

 

 

print id(one)

 

print id(two)

 

print one==two

 

print one is two

 

 

 

c:\Python27\Scripts>python task_test.py

 

3

 

41189456

 

41189456

 

True

 

True

 

 

 

后期添加注释代码:

 

#coding=utf-8

 

 

 

class Singleton(object):

 

    def __new__(cls,*args,**kw):

 

        if not hasattr(cls,'_instance'):

 

            orig=super(Singleton,cls)

 

            cls._instance=orig.__new__(cls,*args,**kw)

 

            #打印返回:type <class '__main__.MyClass'>

 

            print "type", type(cls._instance)#返回类对象的类型

 

           

 

        return cls._instance

 

 

 

class MyClass(Singleton):

 

    a=1

 

one = MyClass()#返回一个类的实例对象

 

two = MyClass()#返回一个同一个实例对象

 

 

 

#返回:one: <__main__.MyClass object at 0x027730D0>

 

print "one:",one

 

#返回也是:two: <__main__.MyClass object at 0x027730D0>

 

print "two:",two

 

 

 

two.a = 3

 

print one.a

 

#3

 

#one和two完全相同,可以用id(), ==, is检测

 

print id(one)

 

#29097904

 

print id(two)

 

#29097904

 

print one == two

 

#True

 

print one is two

 

#True

 

 

 

 结果:

 

c:\Python27\Scripts>python task_test.py

 

type <class '__main__.MyClass'>

 

one: <__main__.MyClass object at 0x027A30D0>

 

two: <__main__.MyClass object at 0x027A30D0>

 

3

 

41562320

 

41562320

 

True

 

True

 

 

 

hasattr(cls,’_instance’):判断对象中是否包含这个属性-类变量

 

类实例对象里是否有这个类变量

 

 

 

 

 

 

 

 

单例用处:

 

http://blog.csdn.net/tanyujing/article/details/14160941

 

 

 

 

 

单例模式的应用场景:

 


1. Windows的Task Manager(任务管理器)就是很典型的单例模式(这个很熟悉吧),想想看,是不是呢,你能打开两个windows task manager吗? 不信你自己试试看哦~ 
2. windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。
3. 网站的计数器,一般也是采用单例模式实现,否则难以同步。
4. 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
5. Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。
6. 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。
7. 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。
8. 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。
9. HttpApplication 也是单位例的典型应用。熟悉ASP.Net(IIS)的整个请求生命周期的人应该知道HttpApplication也是单例模式,所有的HttpModule都共享一个HttpApplication实例.

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM