and replace the previously manual task of passing in enclosing scope values with de-
faults altogether.
Well, almost. There is a catch. It turns out that within a lambda (or def), references to
names in the enclosing scope are actually resolved when the generated function is
called, not when it is created. Because of this, when the function is later called, such
name references will reflect the latest or final assignments made to the names anywhere
in the enclosing scope, which are not necessarily the values they held when the function
was made. This holds true even when the callback function is nested only in a module’s
global scope, not in an enclosing function; in either case, all enclosing scope references
are resolved at function call time, not at function creation time.
This is subtly different from default argument values, which are evaluated once when
the function is created, not when it is later called. Because of that, defaults can still be
useful for remembering the values of enclosing scope variables as they were when you
made the function. Unlike enclosing scope name references, defaults will not have a
different value if the variable later changes in the enclosing scope, between function
creation and call. (In fact, this is why mutable defaults like lists retain their state between
calls—they are created only once, when the function is made, and attached to the
function itself.)
This is normally a nonissue, because most enclosing scope references name a variable
that is assigned just once in the enclosing scope (the self argument in class methods,
for example). But this can lead to coding mistakes if not understood, especially if you
create functions within a loop; if those functions reference the loop variable, it will
evaluate to the value it was given on the last loop iteration in all the functions generated.
By contrast, if you use defaults instead, each function will remember the current value
of the loop variable, not the last.
Because of this difference, nested scope references are not always sufficient to remember
enclosing scope values, and defaults are sometimes still required today. Let’s see what
this means in terms of code. Consider the following nested function (this section’s code
snippets are saved in file defaults.py in the examples package, if you want to experiment
with them).
def simple():
spam = 'ni'
def action():
print(spam) # name maps to enclosing function
return action
act = simple() # make and return nested function
act() # then call it: prints 'ni'
This is the simple case for enclosing scope references, and it works the same way
whether the nested function is generated with a def or a lambda. But notice that this
still works if we assign the enclosing scope’s spam variable after the nested function is
created:
388 | Chapter 7: Graphical User Interfaces