Python3之单例模式

单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。

比如在Django开发中,我们会用到短信验证的业务,如果我们有成千上万的用户同时有发送短信的需求,那么我们就需要创建成千上万的发送短信的对象,实际上只需要调用对象的方法进行发送短信罢了,因此采用单例模式就可以减少创建多余的类对象,节省资源!

本文以5种方式实现单例模式,分别是:使用__new__实现单例使用元类创建单例使用函数装饰器实现单例使用类装饰器实现单例以及import方法

# 使用__new__()实现单例
class A():
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance
    
a1 = A()  # 在创建实例之前会调用__new__()方法
a2 = A()

print(a1, a2)
print(id(a1), id(a2))
print(a1 is a2)

<__main__.A object at 0x000002B48233F4E0> <__main__.A object at 0x000002B48233F4E0>
2974301811936 2974301811936
True
# 使用元类创建单例
class B(type):
    def __init__(self, *args, **kwargs):
        self._instance = None
    def __call__(self, *args, **kwargs):
        if not self._instance:
            self._instance = super().__call__(*args, **kwargs)
        return self._instance

class C(metaclass=B):  # <==> C = B(xx)
    pass

c1 = C()  # <==> c1 = C() = B(xx)(): 调用__call__方法
c2 = C()

print(c1, c2)
print(id(c1), id(c2))
print(c1 is c2)

<__main__.C object at 0x000002B48233FC88> <__main__.C object at 0x000002B48233FC88>
2974301813896 2974301813896
True
# 使用装饰器实现单例
def setfunc(cls):
    instance = {}
    def callfunc(*args, **kwargs):
        if cls not in instance:
            instance[cls] = cls(*args, **kwargs)
        return instance[cls]
    return callfunc

@setfunc
class D():  # <==> D = setfunc(D)
    pass

d1 = D()  # <==> d1 = D() = setfunc(D)() = callfunc()
d2 = D()

print(d1, d2)
print(id(d1), id(d2))
print(d1 is d2)
    
<__main__.D object at 0x000002B48233FDA0> <__main__.D object at 0x000002B48233FDA0>
2974301814176 2974301814176
True
# 使用类装饰器实现单例
class Single():
    def __init__(self, _class):
        self._class = _class
        self._instance = {}
    def __call__(self):
        if self._class not in self._instance:
            self._instance[self._class] = self._class()
        return self._instance[self._class]

@Single
class E():  # <==> E = Single(E)
    pass

e1 = E()  # <==> e1 = E() = Single(E)() ==> 调用__call__()方法
e2 = E()

print(e1, e2)
print(id(e1), id(e2))
print(e1 is e2)
<__main__.E object at 0x000002B482348128> <__main__.E object at 0x000002B482348128>
2974301847848 2974301847848
True

最简单的方式就是从一个.py文件中导入一个实例对象,import是天然的单例模式,这里不做演示了

猜你喜欢

转载自blog.csdn.net/weixin_41599977/article/details/89765963