python实现单例模式的5种方法

作者: Tim在路上 | 来源:发表于2018-10-01 10:54 被阅读0次

    单例模式

    相信大家都知道单例模式

    单例模式最初的定义出现于《设计模式》(艾迪生维斯理, 1994):“保证一个类仅有一个实例,并提供一个访问它的全局访问点。”

    单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。

    那么,为什么不直接使用全局变量,而要搞一个单例出来?单例到底比全局变量好在哪儿?

      首先,全局变量不能保证全局只有一个类的实例,你完全可以声明同一个类的多个实例。当然,如果你注意一点,那么用全局方法保证全局只有一个该类的实例还是可以做到的,但你得很注意,让自己不要在其他地方声明多一个实例。而单例却可以轻松的做到这一点,并能保证全局只有一个该类的实例可被访问。
    
      其次,相对来说,使用单例时,代码会显得优雅一些。
    

    什么时候用单例

      单例的使用主要是在需要保证全局只有一个实例可以被访问的情况,比如系统日志的输出、操作系统的任务管理器等。
    

    一、使用new方法

    class Singleton(object):
        def __new__(cls, *args, **kw):
            if not hasattr(cls, '_instance'):
                orig = super(Singleton, cls)
                cls._instance = orig.__new__(cls, *args, **kw)
            return cls._instance
     
    class MyClass(Singleton):
        a = 1
    

    二、共享属性

    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
    

    创建实例时把所有实例的dict指向同一个字典,这样它们具有相同的属性和方法.

    三、装饰器版本

    def singleton(cls, *args, **kw):
        instances = {}
        def getinstance():
            if cls not in instances:
                instances[cls] = cls(*args, **kw)
            return instances[cls]
        return getinstance
     
    @singleton
    class MyClass:
    

    四、import方法

    作为python的模块是天然的单例模式

    # mysingleton.py
    class My_Singleton(object):
        def foo(self):
            pass
     
    my_singleton = My_Singleton()
     
    # to use
    from mysingleton import my_singleton
     
    my_singleton.foo()
    

    五、使用元类方法

    class Singleton2(type):
        def __init__(self, *args, **kwargs):
            self.__instance = None
            super(Singleton2,self).__init__(*args, **kwargs)
    
        def __call__(self, *args, **kwargs):
            if self.__instance is None:
                self.__instance = super(Singleton2,self).__call__(*args, **kwargs)
            return self.__instance
    
    
    class Foo(object):
        __metaclass__ = Singleton2 #在代码执行到这里的时候,元类中的__new__方法和__init__方法其实已经被执行了,而不是在Foo实例化的时候执行。且仅会执行一次。
    
    
    foo1 = Foo()
    foo2 = Foo()
    print (Foo.__dict__)  #_Singleton__instance': <__main__.Foo object at 0x100c52f10> 存在一个私有属性来保存属性,而不会污染Foo类(其实还是会污染,只是无法直接通过__instance属性访问)
    
    print (foo1 is foo2)  # True
    

    相关文章

      网友评论

        本文标题:python实现单例模式的5种方法

        本文链接:https://www.haomeiwen.com/subject/kifnoftx.html