How do closures and the nonlocal keyword work in Python?

· Category: Python Programming

Short answer

A closure is a nested function that remembers variables from its enclosing scope even after the outer function has finished executing. Use nonlocal to modify those captured variables from the inner function.

Steps

  1. Define an outer function with local variables.
  2. Define an inner function that references those variables.
  3. Use nonlocal to assign to the outer variables.
  4. Return the inner function.
def make_multiplier(factor):
    def multiply(x):
        return x * factor
    return multiply

double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5))  # 10
print(triple(5))  # 15

def make_counter():
    count = 0
    def increment():
        nonlocal count
        count += 1
        return count
    return increment

counter = make_counter()
print(counter())  # 1
print(counter())  # 2

Tips

  • Closures are the foundation of decorators and factory functions.
  • nonlocal sits between global (module scope) and local (function scope).
  • In Python 2, the workaround for nonlocal was to use mutable objects (like a list or dict) to hold state.

Common issues

  • Assigning to an enclosing variable without nonlocal creates a new local variable instead.
  • Using mutable default arguments to simulate closures can cause shared-state bugs.
  • Capturing loop variables in closures inside a loop can lead to late binding; use default arguments to capture the current value.