python单例模式

使用元类控制如何创建一个对象

  • 注意继承type,typepython中创建对象的最顶层入口,typestr,int等都是类,用来创建对象
  • __call__使对象变得可调用,即对象后面直接加小括号,例如a=A(),可以直接用a(),此时自动执行__call__的逻辑
  • hasattr,setattr,getattr用来判断,获取,设置类的属性
class MySingletonMeta(type):
    SPECIAL_STR = "__mySingletonMetaAttr__"

    def __call__(cls, *args, **kwargs):
        if not hasattr(cls, cls.SPECIAL_STR):
            setattr(cls, cls.SPECIAL_STR, super().__call__(*args, **kwargs))
        return getattr(cls, cls.SPECIAL_STR)

使用元类创建一个单例类

以下代码为python3

class MySingleton(metaclass=MySingletonMeta):
    pass

继承单例类

class AA(MySingleton):
    a = 9527

    def __init__(self, a):
        self.a = a


if __name__ == '__main__':
    a = AA(1)
    b = AA(2)
    print(a)    #<__main__.AA object at 0x000001D78B49CF60>,是第一次创建的对象的地址
    print(b)    #<__main__.AA object at 0x000001D78B49CF60>,是第一次创建的对象的地址
    print(a.a)  #1,属性值是第一次创建的对象的值
    print(b.a)  #1,属性值是第一次创建的对象的值,所以不是2

使用__new__创建单例模式

不要用这个方式创建.个人认为,一旦一个对象创建好了,它的属性就不应该再被改变

class SingletonOverride:
    """
    单例模式 原理:“类变量对所有对象唯一”
    这种写法,后面的实例属性会覆盖前者的实例属性
    """

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '__instance__'):
            cls.__instance__ = super().__new__(cls)
        return cls.__instance__

思考

  • 多线程下,创建的对象还是单例吗?解决方案有哪些?
  • 使用__new__的方式还是真正意义上的单例模式吗?
posted @ 2021-02-18 16:47  rm-rf*  阅读(56)  评论(0编辑  收藏  举报