单利模式详细分析


  单利模式:所谓单例模式就是一个类只能创建一个实例化。

          python中的内置函数__new__(), 它跟__init__()一样, 都是对象在被创建出来的时候, 就自动执行的一个函数, init()函数, 是为了给函数初始化属性值的, 而__new__()这个函数, 就是为了给对象在被实例化的时候, 分配一块内存地址, 因此, 我们可以重写__new__()这个方法, 让他在第一次实例化一个对象之后, 分配一块地址, 在此后的所有实例化的其他对象时, 都不再分配新的地址, 而继续使用第一个对象所被分配的地址, 因此, 我们可以在类对象里, 定义一个类属性, 初始值设为None, 如果这个值是None就调用父类的__new__()方法, 为其分配地址, 并返回这个地址(__new__方法一定要返回一个地址)
    
    class Earth(object):
        __instance=None #定义一个类属性做判断
     
        def __new__(cls):
 
            if cls.__instance==None:
                #如果__instance为空证明是第一次创建实例
                #通过父类的__new__(cls)创建实例
                cls.__instance=object.__new__(cls)
                return  cls.__instance
            else:
                #返回上一个对象的引用
                return cls.__instance
 

   1 文件导入的形式:
     将Foo类在某个文件(test1.py)中实例化,赋值给某个变量v。在其他文件如test2.py中引入该实例,多次引用打印其内存地址,发现是一样。
   2 基于__new__来实现单例。
    当程序初始化之前,会先调用__new__方法。在类中实现如下new方法。
    def __new__(cls, *args, **kwargs): 
        if not hasattr(SingletonDBPool, "_instance"):
            with SingletonDBPool._instance_lock:
                if not hasattr(SingletonDBPool, "_instance"):
                    Singleton._instance = object.__new__(cls, *args, **kwargs)
        return Singleton._instance

    3 使用装饰器(decorator),
    #这是一种更pythonic,更elegant的方法,
    #单例类本身根本不知道自己是单例的,因为他本身(自己的代码)并不是单例的
    def singleton(cls, *args, **kw):
        instances = {}
        def _singleton():
            if cls not in instances:
                instances[cls] = cls(*args, **kw)
            return instances[cls]
        return _singleton
 
    @singleton
    class MyClass4(object):
        a = 1
        def __init__(self, x=0):
            self.x = x
 
    one = MyClass4()
    two = MyClass4()


    4 共享属性;所谓单例就是所有引用(实例、对象)拥有相同的状态(属性)和行为(方法)
      所有实例共享属性的最简单最直接的方法就是__dict__属性指向(引用)同一个字典(dict)
      #可参看:http://code.activestate.com/recipes/66531/
    class Borg(object):
        _state = {}
        def __new__(cls, *args, **kw):
            ob = super(Borg, cls).__new__(cls, *args, **kw)
            ob.__dict__ = cls._state
            return ob
 
    class MyClass2(Borg):
        a = 1
 
    one = MyClass2()
    two = MyClass2()
 
    5 使用__metaclass__(元类)的高级python用法
    class Singleton2(type):
        def __init__(cls, name, bases, dict):
            super(Singleton2, cls).__init__(name, bases, dict)
            cls._instance = None
        def __call__(cls, *args, **kw):
            if cls._instance is None:
                cls._instance = super(Singleton2, cls).__call__(*args, **kw)
            return cls._instance
 
    class MyClass3(object):
        __metaclass__ = Singleton2
 
    one = MyClass3()
    two = MyClass3()
 

猜你喜欢

转载自blog.csdn.net/weixin_42322206/article/details/100088214