我在这里遇到了 Peter Norvig 的单例类实现 http://norvig.com/python-iaq.html

def singleton(object, instantiated=[]):
    "Raise an exception if an object of this class has been instantiated before."
    assert object.__class__ not in instantiated, \
        "%s is a Singleton class but is already instantiated" % object.__class__
    instantiated.append(object.__class__)

class YourClass:
    "A singleton class to do something ..."
    def __init__(self, args):
       singleton(self)
       ...

我的问题是,如果我们第二次创建两个 YourClass 实例,为什么 instantiated 不是空列表? instantiated 的范围是什么?

谢谢你。

最佳答案

来自 docs :


instantiated 的值绑定(bind)到函数定义,并且仅在您定义 singleton 时初始化一次。

因此,每次调用该函数时,您将只有一份相同列表的副本:

def test(x, instantiated=[]):
    instantiated.append(x)
    print instantiated

>>> test(3)
[3]
>>> test(5)
[3, 5]
>>> test(6)
[3, 5, 6]

它与:
>>> lst = []

>>> def test(x, instantiated):
...     instantiated.append(x)
...     print instantiated

>>> test(3, lst)
[3]
>>> test(5, lst)
[3, 5]
>>> test(6, lst)
[3, 5, 6]

如果希望 instantiated 在后续函数调用之间隔离,则应将其定义为 local variable :
def test(x, instantiated=None):
    if instantiated is None:
        instantiated = []
    instantiated.append(x)
    print instantiated

>>> test(3)
[3]
>>> test(5)
[5]
>>> test(6)
[6]

10-07 18:25