【问题标题】:python closure local variablespython闭包局部变量
【发布时间】:2012-06-21 16:53:18
【问题描述】:

In this answer 一个单例装饰器就是这样演示的

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() 被调用时

我想我知道这不应该工作(因为分配给实例将是本地的并且在调用之间丢失),但我不明白为什么我会收到这个错误。

【问题讨论】:

  • 一个更完整的@singleton
  • @ehemient 谢谢。总的来说,这是一个非常有用的页面。

标签: python singleton closures


【解决方案1】:

错误的原因是 python 比我更聪明,并且确定实例是由赋值本地化的,并且不会向上范围查找赋值。正如@GeeTransit 在 cmets 中指出的那样,这在 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')

【讨论】:

  • 已经有一段时间了,但我想指出,通过添加nonlocal instances,您可以修复错误。之所以引发它,是因为该函数在第一次使用变量之前没有看到“声明”或任何类型。在这种情况下,nonlocal instancesinstances = some_value 相似,但 some_value 与外部相同。
  • @GeeTransit 已相应编辑!谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-01-21
  • 2018-12-24
  • 1970-01-01
  • 2019-07-24
  • 2016-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多