Python实现单例模式
- 函数装饰器实现单例
from functools import wraps
@wraps
接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。
def singleton(cls: object):
_instance = {}
@wraps(cls)
def inner(*args, **kwargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kwargs)
return _instance[cls]
return inner
@singleton
class Cls1(object):
def __init__(self):
self._name = None
if __name__ == "__main__":
cls1 = Cls1()
cls2 = Cls1()
print(id(cls1) == id(cls2))
print(Cls1.__name__)
print(Cls1.__class__)
True
Cls1
<class 'function'>
- 类装饰器实现单例
class Singleton(object):
def __init__(self):
pass
def __call__(self, cls, *args, **kwargs):
_instance = {}
@wraps(cls)
def inner(*args, **kwargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kwargs)
return _instance[cls]
return inner
@Singleton()
class Cls2(object):
def __init__(self):
_name = None
if __name__ == "__main__":
cls1 = Cls2()
cls2 = Cls2()
print(id(cls1) == id(cls2))
print(Cls2.__name__)
print(Cls2.__class__)
True
Cls2
<class 'function'>
class Singleton(object):
def __init__(self, cls):
self._cls = cls
self._instance = {}
def __call__(self, *args, **kwargs):
if self._cls not in self._instance:
self._instance[self._cls] = self._cls(*args, **kwargs)
return self._instance[self._cls]
@Singleton
class Cls2(object):
def __init__(self):
pass
if __name__ == "__main__":
cls1 = Cls2()
cls2 = Cls2()
print(id(cls1) == id(cls2))
print(Cls2.__class__)
True
<class '__main__.Singleton'>
__new__
关键字实现单例
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
def __init__(self):
pass
if __name__ == "__main__":
single1 = Singleton()
single2 = Singleton()
print(id(single1) == id(single2))
True
metaclass
实现单例
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class Cls4(metaclass=Singleton):
pass
if __name__ == "__main__":
cls1 = Cls4()
cls2 = Cls4()
print(id(cls1) == id(cls2))
True