How is `x = 42; x = lambda: x` parsed?
The variable x
is created by the first assignment, and rebound with the second assignment.
Since the x
in the lambda isn't evaluated until the lambda is called, calling it will evaluate to the most recently assigned value.
Note that this is not dynamic scoping - if it were dynamic, the following would print "99", but it prints "<function ...":
x = 42
x = lambda: x
def test(f):
x = 99
print(f())
test(x)
The first assignment is irrelevant; the x
in the body of the lambda
is bound late:
x = lambda: x # no need for a prior assignment
x = lambda: y # notice: no NameError occurs, *until it is called*
This is the same reason that creating lambdas in a loop is tricky, and is also used to make trees with the standard library defaultdict
:
tree = lambda: defaultdict(tree)
t = tree()
t['foo']['bar']['baz'] = 'look ma, no intermediate steps'