python单例模式的五种实现方式

__new__特殊方法实现

class Singleton:

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

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

s1 = Singleton('first')
s2= Singleton('last')
print(s1 == s2)
>> True
print(s1.name)
>> last

tips: new__方法无法避免触发__init(),初始的成员变量会进行覆盖

装饰器实现

def singleton(cls):
    _instance = {}
    def inner(*args, **kwargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kwargs)
        return _instance[cls]
    return inner

@singleton
class Test:
    def __init__(self, name):
        self.name = name

t1 = Test('first')
t2 = Test('last')
print(t1==t2)
>> True
print(t2.name)
>> first

类装饰器实现

class Singleton:
    def __init__(self, cls):
        self._cls = cls
        self._instance = {}

    def __call__(self, *args):
        if self._cls not in self._instance:
            self._instance[self._cls] = self._cls(*args)
        return self._instance[self._cls]


@Singleton
class Cls2:
    def __init__(self, name):
        self.name = name


cls1 = Cls2('first')
cls2 = Cls2('last')
print(id(cls1) == id(cls2))
>> True
print(cls1.name)
>> first

元类实现

class Singleton1(type):
    def __init__(self, *args, **kwargs):
        self.__instance = None
        super(Singleton1, self).__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        if self.__instance is None:
            self.__instance = super(Singleton1, self).__call__(*args, **kwargs)
        return self.__instance

class C(metaclass=Singleton1):
    def __init__(self, name):
        self.name = name

c1 = C('first')
c2 = C('last')
print(c1 == c2)
>> True
print(c2.name)
>> first

模块实现

Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。

#foo1.py
class Singleton(object):
    def foo(self):
        pass
singleton = Singleton()

#foo.py
from foo1 import singleton

部分内容参考自: python 单例模式的四种实现方法及注意事项

posted @ 2019-07-23 19:20  辣眼睛De小新  阅读(733)  评论(0编辑  收藏  举报