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

枫铃3年前 (2021-07-23)Python260

1.__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(),初始的成员变量会进行覆盖

2.装饰器实现

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
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

3.类装饰器实现

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

4.元类实现

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
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

5.模块实现

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

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

#foo.py
from foo1 import singleton

相关文章

Python urllib与requests、XML和HTMLParser

Python 的内建模块urllib提供了一系列用于操作url的方法 Get urllib的request可以非常方便的抓取URL的内容,通过...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。