简体   繁体   English

Python - locals()和闭包

[英]Python - locals() and closure

I can not find an adequate explanation for this behavior. 我找不到这种行为的充分解释。

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

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

But: 但:

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

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

I understand that in the second case there is a closure, but I can not find a detailed description of what actually is and under what conditions should return the function locals() . 我理解在第二种情况下有一个闭包,但是我找不到实际是什么的详细描述以及在什么条件下应该返回函数locals()

If you don't assign to foo within the closure, Python resolves it to the foo of the scope one level up (and on up until it finds a foo somewhere or throws an exception). 如果你没有在闭包中分配给foo ,Python会将它解析为范围的foo一级(并且直到它在某处发现foo或抛出异常)。

By mentioning foo within b() in the second example, you put foo into the locals within b() , but it resolves to the foo within the body of a() . 通过提foob()在第二个例子中,你把foo到当地人中b()但它解析为foo的身体内a() If you assign, say, foo = 1 in b() , you would see 如果你在b()指定foo = 1 ,你会看到

 {'foo': 0}
 {'foo': 1}

as the output. 作为输出。

locals() built-in function prints local symbol table which is bound to a code object , and filled up when interpreter receives a name in a source code. locals()内置函数打印绑定到代码对象的本地符号表,并在解释器在源代码中接收名称时填充。

Second example, when disassembled, will contain LOAD_GLOBAL foo bytecode instruction in b function code. 第二个例子,当反汇编时,将在b函数代码中包含LOAD_GLOBAL foo字节码指令。 This LOAD_GLOBAL instruction will move up the scope, find outer foo name and bind it to the code object by adding name offset into co_names attribute of the closure's (function b) code object. 这个LOAD_GLOBAL指令将向上移动范围,找到外部foo名称并通过将名称偏移量添加到闭包(函数b)代码对象的co_names属性中将其绑定到代码对象。

locals() function prints local symbol table (as was said before, co_names attribute of function's code object). locals()函数打印本地符号表(如前所述,函数的代码对象的co_names属性)。

Read more about code objects here . 阅读更多有关代码对象的信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM