In Python, if a variable is assigned to in a function, it is
automatically a local variable. This means we do not need to “declare”
local variables. However, if you do not assign to a name in a function,
its value is sought in the outer scopes (clearly it cannot be local,
since nothing assigns to it).
So when you define this function:
def inner():
return i * i
the variable i
must come from an outer scope, thus the closure - it
comes from the i
in the for-loop. Because of the closure it remain
connected to that variable. because you call the function after the loop
has finished, i
is 3
, the last value from the loop. So each call
computes 9
.
When you define the function like this:
def inner(i=i):
return i * i
i
is a local variable (it is defined in the function parameters). Its
default value comes from the value of the for-loop variable i
from the
outer scope, so each function definition has the defaults 1, 2 and 3
respectively. When you call them with no arguments, their default value
is used, and it is different for each function you defined. The variable
i
within the function is a local variable, and not the variable from
the for-loop.
This local/nonlocal choice is made by static inspection of the function.
Personally, I’d probably try to avoid the confusion of names and use a
different name for the parameter verus the loop variable, something like
this:
def inner(x=i):
return x * x
Now there is no source of confusion.
Cheers,
Cameron Simpson cs@cskk.id.au