在这个答案中,单例装饰器被证明是这样的
def singleton(cls):
instances = {}
def getinstance():
print len(instances)
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
但是instances
对于每个装饰的类都是"本地的",所以我试图提高效率和使用
def BAD_singleton(cls):
instances = None
def getinstance():
if instances is None:
instances = cls()
return instances
return getinstance
@BAD_singleton
class MyTest(object):
def __init__(self):
print 'test'
但是,这给出了一个错误
UnboundLocalError: local variable 'instances' referenced before assignment
当调用m = MyTest()
时
不应该起作用(因为对实例的分配将是本地的并且在调用之间丢失),但我不明白为什么我会收到此错误。
错误的原因是 python 比我聪明,并且确定实例是由赋值在本地进行的,并且不会向上查找赋值。 正如@GeeTransit的评论中所指出的那样,这在python3中可以通过nonlocal
def nonlocal_singleton(cls):
instances = None
def getinstance():
nonlocal instances
if instances is None:
instances = cls()
return instances
return getinstance
@nonlocal_singleton
class MyTest(object):
def __init__(self):
print('test')