我试图了解一个类的某个单例装饰器实现是如何工作的,但我只是感到困惑。
以下是代码:
def singleton(cls):
instance = None
@functools.wraps(cls)
def inner(*args, **kwargs):
nonlocal instance
if instance is None:
instance = cls(*args, **kwargs)
return instance
return inner
@deco
是cls = deco(cls)
的合成糖,因此在此代码中,当我们定义我们的cls
类并使用此singleton
装饰器包装它时,{{1}不再是一个班级,而是一个功能。 Python动态搜索变量链接到哪些对象,所以稍后我们尝试创建一个类的实例,这行代码运行cls
,我们不会进入无限递归? instance = cls(*args, **kwargs)
此时不是一个类,它是一个函数,因此它应该调用自身,进入递归。
但它运作正常。创建单线程,不会发生递归。它是如何工作的?
答案 0 :(得分:4)
函数inner
关闭了局部变量cls
。
cls
是对班级的引用。它永远不会反弹到其他任何东西。
装饰器返回一个返回实例的函数,但这不会影响内部cls
变量引用的内容
答案 1 :(得分:3)
cls
是对传递给装饰器的原始类的引用。它保留了调用装饰器时的值。它的价值是"被困"在装饰器返回的函数中;由于不明原因,这被称为闭包。大多数函数是第一类对象的语言都具有此功能。
答案 2 :(得分:2)
<class '__main__.TryMe'>
<__main__.TryMe object at 0x10231c9d0>
你会得到:
{{1}}