Python - locals()和闭包

时间:2012-08-09 20:39:35

标签: python closures locals

我无法找到这种行为的充分解释。

>>> def a():
...     foo = 0
...     print locals()
...     def b():
...         print locals()
...     b()

>>> a()
{'foo': 0}
{}

可是:

>>> def a():
...     foo = 0
...     print locals()
...     def b():
            foo
...         print locals()
...     b()

>>> a()
{'foo': 0}
{'foo': 0}

据我所知,在第二种情况下有一个闭包,但我找不到实际内容的详细描述,在什么条件下应返回函数locals()

2 个答案:

答案 0 :(得分:5)

如果您未在关闭内分配给foo,则Python会将其解析为范围的foo一级(并且直至找到foo在某处或抛出异常)。

在第二个示例中提到foo中的b(),您将foo放入b()内的本地人,但它会解析为foo内的a() foo = 1的正文。如果您在b()中指定 {'foo': 0} {'foo': 1} ,则会看到

{{1}}

作为输出。

答案 1 :(得分:3)

locals()内置函数打印绑定到代码对象的本地符号表,并在解释器收到源代码中的名称时填充。

第二个例子,当反汇编时,将在 b 功能代码中包含 LOAD_GLOBAL foo 字节码指令。这个LOAD_GLOBAL指令将向上移动范围,找到外部foo名称并通过将名称偏移量添加到闭包(函数b)代码对象的 co_names 属性中将其绑定到代码对象。

locals()函数打印本地符号表(如前所述,函数代码对象的co_names属性)。

详细了解代码对象here