Python|单例及实现
内容
保证一个类只有一个实例,并提供一个访问它的全局访问点。
使用场景
当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
优点
- 对唯一实例的受控访问。
- 单例相当于全局变量,但防止了命名空间被污染。
装饰器方法
思路
装饰器里面的外部变量定义一个字典,里面存放这个类的实例。当第一次创建的时候,就将这个实例保存到这个字典中。以后每次创建对象的时候,都去这个字段中判断一下,如果已经被实例化,就直接取这个实例对象,如果不存在就保存在字典中。
实现
class Singleton(type):
# 创建类属性 _instances 用来保存对象
_instances = {}
def __call__(cls, *args, **kwargs):
# 调用时,判断 _instances 中是否存在该类的对象
# 若不存在,则正常调用获取对象并添加到 _instances 中,然后返回该对象
# 若存在,则直接返回该类的对象
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
装饰器单例特点
- 使用装饰器实际上为
singleton(Singleton)
返回的函数_singlenton
。所以装饰后的类使用type()
判断的类型都为 function,由于该特性单例类无法直接被继承; - 装饰器单例类只会在第一次创建对象时执行
__init__
,适合只需初始化一次或初始化操作耗时较长的类,例如全局配置类或模型类。