Python › Functions & Scope
How does a closure capture variables from its enclosing scope, and what pitfall occurs when creating multiple closures inside a loop?
AdvancedAnswer
A closure captures enclosing variables BY REFERENCE (not by value at creation time), meaning it sees whatever the variable's value is when the closure ACTUALLY RUNS — creating multiple closures in a loop that all reference the SAME loop variable means they all end up seeing its FINAL value, a classic and common bug.
functions = []
for i in range(3):
functions.append(lambda: i) # all three closures capture the SAME 'i' variable
print([f() for f in functions]) # [2, 2, 2] -- NOT [0, 1, 2] as might be expected!
# Fixed with a default argument, evaluated at DEFINITION time per-iteration:
functions_fixed = [lambda i=i: i for i in range(3)]
print([f() for f in functions_fixed]) # [0, 1, 2]Real-world example Debugging a classic closure bug where multiple queued callbacks unexpectedly all report the SAME final loop value.