I have created a nested closure
which looks as below:
def incrementer(n):
def inner(start):
current = start
def inc():
nonlocal current
current = n
return current
return inc
return inner
fn = incrementer(2)
Now, when I print value of co_freevars
for fn
I get below output:
print(fn.__code__.co_freevars) -> ('n',)
My understanding is that it should be ('current', 'n')
because there are 2 free variables
here.
Why print(fn.__code__.co_freevars)
is not printing ('current', 'n')
?
CodePudding user response:
You define current
in inner
, so it's a normal local variable there. current
is a closure variable in inc
.
Consider:
inner = incrementer(2)
inc = inner(1)
print(inner.__code__.co_freevars)
print(inc.__code__.co_freevars)
Output:
('n',)
('current', 'n')
Another example to drive home the point:
def outer():
var1 = 1
var2 = 2
var3 = 3
var4 = 4
def middle():
var1
var2
def inner():
var2
var4
return inner
return middle
middle = outer()
inner = middle()
print(outer.__code__.co_freevars)
print(middle.__code__.co_freevars)
print(inner.__code__.co_freevars)
Output:
()
('var1', 'var2', 'var4')
('var2', 'var4')
first print:
outer
has no closure variables.
second print:
var1
, var2
and var4
are used in middle
and come from an outer scope. Yes, var4
is used in middle
. In the definition of inner
, which is defined inside of middle
.
third print:
var2
and var4
are used in inner
and come from an outer scope.