单例模式的几种实现方式
1._new_(cls, *args, **kw) 方法实现
class Singleton(object):
"""
构造方法 new 方法至少需要一个 cls 参数,实例化时,解释器会自动填入;
若 _instance = {}, 则
if cls not in cls._instance:
cls._instance[cls] = object.__new__(cls, *args, **kw)
不要 = cls(), cls() 就是调用的 cls.__new__(),会报【超出最大递归深度】错误;
"""
_instance = None # 新建一个类属性:需要使用类名前缀来访问
def __new__(cls, *args, **kw): # 创建实例时,判断是否已经存在,存在,返回,不存在,创建
if cls._instance is None:
cls._instance = object.__new__(cls, *args, **kw) # 不要调用自己的,会无限递归; cls() 就是调用的 cls.__new__()
return cls._instance # new 方法中返回实例对象
def __init__(self):
pass
sing1 = Singleton()
sing2 = Singleton()
sing1 is sing2 # true
2.函数装饰器实现:实例化前先调用这个装饰器返回的 inner() 函数,再返回实例
def singleton(cls): # 自定义装饰器, 函数中再嵌套一个函数, 并返回嵌套函数名
"""
用不可变的 类地址 作为键,其 实例 作为值,
每次创造实例时,首先判断该类是否存在实例,存在,直接返回该实例即可,否则新建一个实例并存放在字典中.
不要 _instance = None, 否则 inner 函数中有赋值,_instance 只会在函数作用域搜索,判断时会报错;
"""
_instance = {} # 新建空字典
def inner(): # 判断是否已有实例,如无,则新建一个实例并返回
if cls not in _instance:
_instance[cls] = cls()
return _instance[cls] # 返回的是实例对象,别搞蒙了
return inner
@singleton
class Cls():
def __init__(self):
pass # 可以照常添加属性和方法
cls1 = Cls()
cls2 = Cls()
cls1 is cls2 # True
3.类装饰器实现
"""
启用 __call__(self) 函数
"""
class Singleton(object): # 自定义类装饰器
def __init__(self, cls): # 赋初值
self.cls = cls
self.instance = {}
def __call__(self): # 调用类装饰器时,判断是否已存在
if self.cls not in self.instance:
self.instance[self.cls] = self.cls()
return self.instance[self.cls] # 返回实例对象
@Singleton
class Cls(object):
def __init__(self):
pass
cls4 = Cls()
cls5 = Cls()
cls4 is cls5 # True
"""
元类->类->实例,简单来说,就是类是由元类创建的,type 是内置的元类,也可以自定义元类;
下面两条语句会创建相同的 type 对象:
class X:
a = 1
X = type('X', (object,), dict(a=1)) # 动态的创建类对象,dict 也可以直接用 {'a':1, 'func_name': func_name}
"""
class Singleton4(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton4, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class Cls4(metaclass=Singleton4):
pass
cls1 = Cls4()
cls2 = Cls4()
print(id(cls1) == id(cls2))