实现单例所利用的装饰器传参原理:
def fun1(fun):
print('fun1 action')
return fun
@fun1
def fun2():
print('fun2 action')
# 在函数执行时,类对象会作为参数传给 装饰器
if __name__ == '__main__':
fun2()
# 运行结果:
fun1 action
fun2 action
实现单例:
利用了闭包特性,具有全局唯一性:
def singleton(w): # w 值得是作为参数传入的 类对象,此例中为 Student
instances = {}
def get_instance(*args, **kwargs):
if w not in instances:
# 灵魂:实例化w对象,并存入instance中
instances[w] = w(*args, **kwargs)
return instances[w]
return get_instance
@singleton
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
student = Student('f', 25)
print(id(student))
print(student.name)
student1 = Student('w', 25)
print(id(student1))
print(student1.name)
# 运行结果:
140647278726392
f
140647278726392
f
注意:正是应为使用了装饰器来实现单例,它与重写 __ new __ 方法的方式实现单例有所区别
在装饰器中使用了闭包的特性,所以使用装饰器达到的单例具有全局唯一性,即:第一次实例化后就永久有效,后面实例化类对象无法更改类的所有属性。但是使用 __ new __ 方法的单例,在后面使用时可以对属性进行更改。
使用重写 __ new __方法来实现单例
class A(object):
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
# 将使用 __new__ 方法创建的类作为 值 存储在cls的类属性中
cls._instance = object.__new__(cls)
return cls._instance
else:
return cls._instance
def __init__(self, f):
self.f = f
cc = A(23)
print(id(cc))
print(cc.f)
cc = A(66)
print(id(cc))
print(cc.f)
# 运行结果:
140197397482632
23
140197397482632
66
当然两种方式实现的都是单例,只是有所区别罢了,各自有各自的妙用。