python单例模式

单例模式即类有且只有一个实例化对象。
单例模式适用于日志的打印,数据库的操作,即打印机的后台处理。

UML图

Singleton类有一个私有的属性instance保存着Singleton类的实例,有一个instance方法返回Singleton实例对象。
在这里插入图片描述

实现方式

经典式实例化

Python经典方法实现单例模式主要通过覆盖构造函数__new__。
代码

class SingleInstance:
    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super(SingleInstance, cls).__new__(cls)
        return cls.instance

a = SingleInstance()
b = SingleInstance()
print(a,b)

结果

<__main__.SingleInstance object at 0x0000017DAE4AC0F0> <__main__.SingleInstance object at 0x0000017DAE4AC0F0>

可以看到2个实例对象实际上是同一个。

懒惰式实例化

懒惰式实例化不直接将类实例化,而是通过调用一个接口get_instance,接口会检查类属性__instance是否存在,如果有就直接返回这个实例,如果没有就实例化类。
代码

class SingleInstance:
    __instance = None

    @classmethod
    def get_instance(cls):
        if not cls.__instance:
            cls.__instance = SingleInstance()
        return cls.__instance


a = SingleInstance.get_instance()
b = SingleInstance.get_instance()
print(a, b)

结果

<__main__.SingleInstance object at 0x00000264601A7358> <__main__.SingleInstance object at 0x00000264601A7358>

可以看到2个实例对象实际上是同一个。

模块式实例化

代码
test模块中:

class SingleInstance:
    def __call__(self, *args, **kwargs):
        print('this is single instance')

a = SingleInstance()

test2模块中:

from test import a

b = a()
c = a()

因为python的模块只会导入一次,所以python中所有的模块都是单例模式。所有无论怎么调用都只会生成一个SingleInstace对象。

通过元类实现单例模式

代码

class MetaSingleInstance(type):
    __instance = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls.__instance:
            cls.__instance[cls] = super(MetaSingleInstance, cls).__call__(*args, **kwargs)
        return cls.__instance[cls]


class SingleInstance(metaclass=MetaSingleInstance):
    pass

a = SingleInstance()
b = SingleInstance()
print(a, b)

结果

<__main__.SingleInstance object at 0x000001E9DA06C0F0> <__main__.SingleInstance object at 0x000001E9DA06C0F0>

简单理解为当你创建类SingleInstance,实际就是实例化了MetaSingleInstance,之后你在创建a和b的时候相当于调用了这个实例。
而调用类的实例实际调用这个类的__call__函数。

SingleInstance = MetaSingleInstance()
a = SingleInstance() # 等同于MetaSingleInstance()()

Monostate单例模式

也称为单态模式,和单例模式不同的是,它的状态和行为是相同的,但是可能不只有一个实例对象。
代码

class A:
    __shared_state = {'w': 2}

    def __init__(self):
        self.x = 1
        self.__dict__ = self.__shared_state


a = A()
b = A()
b.x = 4
print(b.__dict__)
print(a.__dict__)

结果

{'w': 2, 'x': 4}
{'w': 2, 'x': 4}

修改了实例b的x值,a的x值也随着变化。
还可以通过构建函数实现该模式。
代码

class A:
    __sherad_state = {}
    def __new__(cls, *args, **kwargs):
        obj = super(A, cls).__new__(cls, *args, **kwargs)
        obj.__dict__ = cls.__sherad_state
        return obj

a = A()
b = A()
b.x = 4
print(b.__dict__)
print(a.__dict__)

结果

{'x': 4}
{'x': 4}
©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页