Python中自由变量的搜索顺序是什么?

时间:2010-07-30 20:41:00

标签: python scope closures

具体来说,自由变量如何在定义中绑定类的方法?它可能是这样的:

  1. 封闭功能(临时)范围=>生成闭包
  2. 全球(永久)范围=>不生成闭包(只在方法体执行时查找)
  3. 引发UnboundLocalError()
  4. 以下是两个例子:

    globalname = 0
    class Test(object):
        def method(self):
            print globalname
            print Test
    
    def outer():
        localname = 1
        class Test(object):
            def method(self):
                print globalname
                print localname
                print Test
        return Test
    
    Test().method.__func__.__closure__
    # None
    outer()().method.__func__.__closure__
    # (<cell at 0xb7d655b4: type object at 0x82412bc>, <cell at 0xb7d655cc: int object at 0x81b20b0>)
    

    我找不到很多关于如何在定义时对待它们的文档。以上解释是否正确?

1 个答案:

答案 0 :(得分:2)

Python假设变量是本地的,当且仅当它在当前代码块中被赋值时才是。所以

spam = 0
def ham:
    print( spam )

会使垃圾邮件成为全局变量,但

spam = 0
def ham:
    spam = 0
    print( spam )

将创建一个单独的变量,ham的本地变量。闭包抓取封闭范围的所有局部变量。在您的第一个示例中,没有局部变量,因此没有闭包;在第二个中,localname被分配,因此method是一个闭包。

与Python一样,有这种假设的方法。 global关键字将变量声明为全局(!),例如。

spam = 0
def ham:
    global spam
    spam = 0
    print( spam )

成为一个闭包。 Py3k引入了nonlocal关键字,它告诉Python向上查看范围,直到找到变量名并引用它。