When a nested function must update state owned by its enclosing function, use nonlocal. It makes assignments target the enclosing binding instead of creating a new local one. Python still resolves names through the LEGB sequence: local, enclosing, global, and built-ins. section 6.5
Counting calls with enclosed state
def foo(): call_counter = 0 def bar(y): nonlocal call_counter call_counter += 1 return f'y = {y}, call_counter = {call_counter}' return bar b = foo() for i in range(10, 100, 10): print(b(i)) Each call to b updates the same call_counter in foo, producing counts from 1 through 9. section 6.5
def foo():
call_counter = 0 #1
def bar(y):
nonlocal call_counter #2
call_counter += 1 #3
return f'y = {y}, call_counter = {call_counter}'
return bar
b = foo()
for i in range(10, 100, 10): #4
print(b(i)) #5
Inspect the complete nested-function example, including the declaration, mutation, returned function, and repeated calls. section 6.5

