class Singleton:
"""
单例类装饰器,可以用于想实现单例的任何类。注意,不能用于多线程环境。
"""
def __init__(self, cls):
""" 需要的参数是一个类 """
self._cls = cls
def Instance(self):
"""
返回真正的实例
"""
try:
return self._instance
except AttributeError:
self._instance = self._cls()
return self._instance
def __call__(self):
raise TypeError('Singletons must be accessed through `Instance()`.')
def __instancecheck__(self, inst):
return isinstance(inst, self._decorated)
# 装饰器
@Singleton
class A:
"""一个需要单列模式的类"""
def __init__(self):
pass
def display(self):
return id(self)
if __name__ == '__main__':
s1 = A.Instance()
s2 = A.Instance()
print(s1, s1.display())
print(s2, s2.display())
print(s1 is s2)
这是网上看到的单例模式实现,他的装饰器是一个类,但是我在网上看到的关于装饰器的都是函数,按照我的理解,如果装饰器是个函数的话,会将@下面的函数传入@的函数,@的函数回返回一个函数,这个函数回执行传入的函数,和一些其他的操作。但是如果@的是一个装饰器的话应该怎么理解呢,按这段代码看 A应该是传进了Singleton的__init__方法,但是调用又是A.Instance(),这是继承关系吗,还有__instancecheck__是干嘛的,self._decorated又是什么意思?实在无法理解
这里是个人对这些代码的理解,希望能为你提供一些线索:
@Singleton装饰class A 的时候,也就是以class A 作为参数给 Singleton(self._cls),就已经实例化了Singleton类并且命名为A。
然后A.instance()是调用instance()方法把在Singleton类的A里面的self._cls实例化,那么classA 的实例就变成了Singleton类实例A的一个成员属性。 这有点类似于inner class,或者nested class,inner class可以使用外部class的属性和方法,但是应该与继承有区别的。
下面这段应该是这样的:self._decorated其实就是self._cls, 我在下面网页找到类似代码,然后改了self._decorated,运行结果一样,至于为什么会这样我不了解。
http://outofmemory.cn/code-sn...
def __instancecheck__(self, inst):
__instancecheck__(self, inst):是python的魔法方法,当执行 print(isinstance(s2,A)) 时候就会触发这方法,用以判别其實例是否某class 的实例。
把def instance() 改成这样:
def Instance(self):
运行 s1 is s2 会返False。
我们知道没有改之前,因为try except 会让 instance() return self._instance, 如果没有的话就实现一个。 造成 s1 和s2 两个id一样,我的理解应该是同一个instance吧,s1 is s2 返回True。
而改了之后,s1 和s2 就不同id了, 然后 s1 is s2 就返回False。
call 讓 A() 出錯,所以要用instance() 訪問A以實現被decorated 的class