Closures & Variable Capture
How closures capture variables, the loop lambda gotcha, nonlocal, and UnboundLocalError
Free tier: read the explanation here. Upgrade to Pro for Drills, Speed challenges & Mastery badges.
UpgradeKnowledge Debt detected
You can study this freely — but your score may plateau if these foundations have gaps. The Mastery badge requires them to be solid.
Explanation
A is a function that remembers the variables from its even after that scope has finished.
Basic closure:
python def make_counter(start=0): count = start def increment(): nonlocal count # needed to modify enclosing variable count += 1 return count return increment counter = make_counter() counter() # 1 counter() # 2
The UnboundLocalError trap:
python x = 10 def f(): print(x) # UnboundLocalError! Python sees x = x + 1 below x = x + 1 # and decides x is local throughout the function `` Python decides at whether a variable is local or not. If it's assigned anywhere in the function, it's considered local everywhere in that function.
The loop lambda gotcha (a classic interview trap): ``python funcs = [lambda: i for i in range(3)] print([f() for f in funcs]) # [2, 2, 2] — NOT [0, 1, 2] All lambdas capture the same i variable :by-reference[The closure stores a pointer to the variable itself, not a copy of its value — so if the variable changes later, the closure sees the new value] not by value. By the time they run, i` is 2.
Fix — capture by value using default argument:
python funcs = [lambda i=i: i for i in range(3)] print([f() for f in funcs]) # [0, 1, 2] ✓ The i=i creates a new local variable i` for each lambda, bound to the current loop value.
Examples
Closure as a configurable function factory
Each call to make_multiplier creates a new closure with its own enclosing scope
def make_multiplier(factor):
def multiply(x):
return x * factor # captures 'factor' from enclosing scope
return multiply
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5)) # 10
print(triple(5)) # 15
# Each closure has its OWN copy of 'factor'How well did you understand this?
Next in Python Core
Lambdas