Python - locals () and closure

I cannot 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’t find a detailed description of what actually exists and under what conditions the function locals() should return.

+4
source share
2 answers

The locals () built-in function prints a local character table that is bound to a code object and populated when the interpreter receives a name in the source code.

The second example, when disassembling, contains the LOAD_GLOBAL foo bytecode command in b . This LOAD_GLOBAL command will move up the field, find the external name foo and associate it with the code object, adding the name offset to the co_names attribute of the object of the closing code (function b).

Function

locals () prints a table of local characters (as mentioned earlier, the co_names attribute of the function code object).

Read more about code objects here .

+3
source

Unless you assign foo to close, Python resolves its foo region one level up (and up until it finds foo somewhere or makes an exception).

Mentioning foo inside b() in the second example, you put foo in the locales within b() , but it resolves foo inside the body of a() . If you assigned, say, foo = 1 to b() , you will see

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

as a conclusion.

+5
source

All Articles