How is `x = 42; x = lambda: x` parsed?
x is created by the first assignment, and rebound with the second assignment.
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
tree = lambda: defaultdict(tree) t = tree() t['foo']['bar']['baz'] = 'look ma, no intermediate steps'