当我在python中观看有关单身人士的一些代码时,我决定自己编写。
这是我的第一个代码:
def singleton(cls):
instance = False
def constructor(*args,**kwargs):
if not instance:
instance = cls(*args,**kwargs)
return instance
return constructor
但是当我测试它时,解释器告诉我'if'必须在if条件下使用之前声明,最后我想出如下:
def singleton(cls):
cls._instance = False
def constructor(*args,**kwargs):
if not cls._instance:
cls._instance = cls(*args,**kwargs)
return cls._instance
return constructor
它按预期工作:
>>> @singleton
>>> class A: pass
>>> a=A()
>>> id(a)
33479456
>>> b=A()
>>> id(b)
33479456
为什么第一个例子的闭包不起作用。
编辑:错误是
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "singleton.py", line 4, in constructor
if not instance:
UnboundLocalError: local variable 'instance' referenced before assignment
答案 0 :(得分:3)
您的第一次关闭无效,因为在constructor
功能中,您已分配到instance
。这使instance
成为constructor
内的本地名称,并在分配之前访问了该本地名称。
在Python 3中,您可以使用nonlocal instance
来声明instance
的范围。在Python 2中,您无法根据需要访问该instance
外部名称。
此外,单身人士在Python中并不常见。为什么不一次实例化你的课程?为什么试图欺骗Python的行为与它不同?或者创建一个工厂函数来生成要使用的实例?
答案 1 :(得分:0)
Closure-variables在Python中是只读的,因此当您尝试将值赋给实例时,Python无法执行此操作。错误消息有点误导,因为声明了实例,它只是在闭包内部不可写。