Use nonlocal when a nested function must assign to a variable owned by an enclosing function. Without it, assignment creates a new local name; global is the wrong tool when the variable is not global. section 7.5
Reason about the name with LEGB: Python searches the local function, enclosing functions, global namespace, and built-ins. Nested functions can therefore read an enclosing value and update it with nonlocal. section 7.5
Build a call counter
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() print(b(10)) # y = 10, call_counter = 1 print(b(20)) # y = 20, call_counter = 2 The returned nested function retains access to call_counter, while nonlocal makes each assignment update the enclosing value. section 7.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 counter listing and follow the declaration, increment, returned function, and repeated calls. section 7.5

