I wrote about closures earlier in This Nested Function Definition Use Case Article, but the names and values of free variables are for function objects. I tried to find out how it is stored inside. (Hereafter, Python 3 is assumed.)
Free Python variables are variables that are used in a block of code (not global variables) but are not defined within that block and Description /reference/executionmodel.html).
For example, in the code below, the variable y is used inside a nested bar function, but it is defined inside the definition block of the outer foo function. So y is a local variable of the function foo and a free variable of the bar function.
python
def foo():
y = "I'm free in bar."
def bar():
print(y)
y = "I'm still free in bar."
return bar
foo returns bar, so to call bar you need two parentheses like this:
python
>>> foo()()
I'm still free in bar.
By the way, the value of y is not the time when bar is defined, but the value when it is called. In the above example, y is defined twice in foo, but you can see that it is a string defined later.
Now, as for the main subject, on the outer function foo object side, the variable name y used from the nested function is in the co_cellvars member (tuple) of its own code object ( __code__). I am.
python
>>> foo.__code__.co_cellvars
('y',)
On the other hand, on the bar object side, y is named as a free variable in the co_freevars member of the code object. (The foo () below is bar.)
python
>>> foo().__code__.co_freevars
('y',)
The contents of the free variable are contained in the tuple of the __closure__ attribute as a cell object, and can be obtained as cell_contents as follows.
python
>>> foo().__closure__[0].cell_contents
"I'm still free in bar."
Recommended Posts