In a new scope, as a function, markup is performed.
Thus, the locales of an expression are limited only by the names specified in the loop, in this case arg
. Local parent functions are not taken into account, since closures are only associated at compile time. Names referenced by eval()
cannot use closure.
The following does not work either:
>>> ARGS = ('a', 'b') >>> def bar(a, b): ... def foo(): ... for arg in ARGS: ... eval(arg) ... return foo ... >>> print bar("A", "B")() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in foo File "<string>", line 1, in <module> NameError: name 'a' is not defined
The names a
and b
not available to the internal function foo
unless the compiler has determined that this function really needs access to them:
>>> def bar2(a, b): ... def foo(): ... a, b ... for arg in ARGS: ... eval(arg) ... return foo ... >>> print bar2("A", "B")() None >>> print bar2("A", "B").func_closure (<cell at 0x1051bac20: str object at 0x104613328>, <cell at 0x1051bacc8: str object at 0x1045971e8>) >>> print bar2("A", "B").__code__.co_freevars ('a', 'b')
Here, the string a, b
can refer only to the parent scopes (they are not assigned by foo()
themselves), so the compiler created a closure for them, and the names became available as local within foo()
.
List conventions in Python 2 do not have their own namespace, a missed fix in Python 3 and not extended to dict and sets understanding. See Python list rename names even after understanding. Is it correct?