How it works
nonlocal selects an existing binding in the nearest enclosing function scope. It is useful when a nested function must rebind state retained by its enclosing function.
It cannot create a new enclosing binding or select a module-level name. If no suitable enclosing binding exists, the declaration is a syntax error. Reading an enclosing name alone does not require nonlocal.
Choices and common mistakes
Use closures for small, focused state. A class can be clearer when there are several related operations or many fields.
Different calls to the outer function can create independent state. Multiple users of the same returned function share that one closure.
Try it yourself
Create two counters starting at different numbers. Alternate their calls and show that each retains its own value.
Syntax
def counter():
value = 0
def next_value():
nonlocal value
value += 1
return value
return next_valueExamples
Create an independent counter
Persist a value between calls to a returned function.
def make_counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
counter = make_counter()
print(counter(), counter())- make_counter creates count and returns increment. nonlocal lets increment rebind that enclosing count.
- The second call observes the value left by the first. The enclosing function need not still be executing for its binding to remain available.
- Use a closure for a local sequence generator when a full class would add little clarity.
- Expected output: 1 2
Keep factories separate
Demonstrate that each factory call owns a different binding.
def make_counter(start):
def increment():
nonlocal start
start += 1
return start
return increment
left = make_counter(0)
right = make_counter(10)
print(left(), right(), left())- The two make_counter calls create separate start bindings. left and right close over different state.
- The final left call advances only the first counter. The displayed values reveal the separation.
- Separate closures can track independent workflows, but calls on one closure still share its state.
- Expected output: 1 11 2
Retain the best value
Update enclosing state only when a better candidate arrives.
def make_best():
best = None
def consider(score):
nonlocal best
if best is None or score > best:
best = score
return best
return consider
consider = make_best()
print(consider(4), consider(2), consider(7))- None marks the initial absence of a score. The short-circuit condition avoids comparing an integer with None.
- Only a larger score rebinds best; a smaller score leaves the retained result unchanged.
- This can summarise a stream of measurements while keeping just one value in memory.
- Expected output: 4 4 7
Best practices
- Use closures for small, focused state. A class can be clearer when there are several related operations or many fields.
- Different calls to the outer function can create independent state. Multiple users of the same returned function share that one closure.
Runtime & versions
Python interpreter. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
Python language reference