python三种方法创建单例模式
# 方法一,装饰器
from functools import wraps
def single_instance(cls):
"""装饰器实现单例模式,装饰器相当于把类给包了起来,强制返回一个对象"""
_instance = None
@wraps(cls)
def wrapper(*args, **kwargs):
nonlocal _instance
if _instance is None:
_instance = cls(*args, **kwargs)
return _instance
return wrapper
@single_instance
class Test1:
def __init__(self, name):
self.name = name
print("Test init..., name=%s" % self.name)
# 方法二 __new__方法
class Test2:
_instance = None
def __init__(self, name):
self.name = name
print("Test2 init..., name=%s" % self.name)
def __new__(cls, *args, **kwargs):
"""__new__主要做的是给实例分配空间,__init__则是在该空间上进行初始化,既然是单例模式,那么空间地址肯定一样,这里做限制"""
print(‘__new__, args=‘, args, ‘,kwargs=‘, kwargs)
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
# 方法三 元类
class SingleType(type):
"""
普通类相当于是元类的实例,所以在类完成定义时其实是调用元类的__init__方法,而生成类的实例,如 Test(‘AIF‘)则是调用元类的__call__方法
这个跟普通类和实例的关系其实是一样的。如 t = Test(‘AIF‘), 生成t会调用Test的__init__方法,而t()则会调用Test的__call__方法
"""
def __init__(self, *args, **kwargs):
self._instance = None
super().__init__(*args, **kwargs)
def __call__(self, *args, **kwargs):
if self._instance is None:
self._instance = super().__call__(*args, **kwargs)
return self._instance
class Test3(metaclass=SingleType):
def __init__(self, name):
self.name = name
print("Test3 init..., name=%s" % self.name)
if __name__ == ‘__main__‘:
"""测试,Test1, Test2, Test3"""
a = Test3(‘AIF‘)
b = Test3(‘AIF333‘)
print(‘a=b is %s, id(a)=%s, id(b)=%s‘ % (a is b, id(a), id(b)))
print(‘a.name=%s, b.name=%s‘ % (a.name, b.name)) 相关推荐
fraternityjava 2020-06-14
Kele0 2020-05-30
ahnuzfm 2020-05-07
gongruitao 2020-05-02
elizabethxxy 2020-04-27
xiaoemo0 2020-04-08
付春杰Blog 2020-03-26
JF0 2020-03-20
ahnuzfm 2020-02-03
Ingram 2020-01-16
缘起宇轩阁 2019-12-30
gongruitao 2020-01-04
zuixin 2020-01-03
pengkunstone 2019-12-27
waitui00 2019-12-22