2

当我在看一些关于 python 中单例的代码时,我决定自己编写。

这是我的第一个代码:

def singleton(cls):
    instance = False
    def constructor(*args,**kwargs):
        if not instance:
            instance = cls(*args,**kwargs)
        return instance
    return constructor

但是当我测试它时,解释器告诉我在 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
4

2 回答 2

3

您的第一个闭包不起作用,因为在您的constructor函数内部,您分配了instance. 这会instance在 内部生成一个本地名称constructor,并且您在分配给它之前访问了该本地名称。

在 Python 3 中,您可以使用nonlocal instance来声明instance. 在 Python 2 中,您无法随意访问该外部instance名称。

此外,单例在 Python 中并不常见。为什么不只实例化你的类一次呢?为什么要试图诱使 Python 表现出与它不同的行为?或者创建一个工厂函数来生成要使用的实例?

于 2012-04-14T23:20:35.950 回答
0

闭包变量在 Python 中是只读的,因此当您尝试为实例赋值时,Python 无法做到。错误消息有点误导,因为声明了实例,它在闭包内是不可写的。

于 2012-04-14T23:19:02.200 回答