Python Closures
In this page:
What is a Closure?
A closure is a function that "remembers" the variables from the scope it was defined in, even after that outer function has already finished running and would otherwise have discarded them.
Example: What is a Closure?
def outer():
message = "Hi"
def inner():
print(message)
return inner
closure = outer()
closure()
Preserving Outer State
Because a closure locks in specific values from its enclosing scope, you can use one to generate specialized helper functions on demand — like a make_multiplier(3) that returns a function which always multiplies by 3, without hardcoding that 3 everywhere it's needed.
Example: Preserving Outer State
def make_multiplier(factor):
def multiplier(x):
return x * factor
return multiplier
times3 = make_multiplier(3)
print(times3(10))
Inspecting Closures
Every closure exposes a __closure__ attribute containing "cell" objects that hold references to the exact variables it captured, which is how Python keeps those values alive after the enclosing function has otherwise returned.
Example: Inspecting Closures
def make_multiplier(factor):
def multiplier(x):
return x * factor
return multiplier
times3 = make_multiplier(3)
print(times3.__closure__[0].cell_contents)
Dynamic State Modifications
The nonlocal keyword lets a closure not just read but actually modify a captured variable from its enclosing scope, which is how you can build a simple counter or accumulator using only nested functions instead of a class.
Example: Dynamic State Modifications
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
counter = make_counter()
print(counter())
print(counter())
When to Use Closures
Closures are a lightweight alternative to defining a whole class when you only need to bundle one small piece of behavior with some remembered state — reach for a class instead once you need multiple related methods sharing that state.
Example: When to Use Closures
def make_counter(): # closure: one small behavior + state
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
# A class would be overkill here for just one counter method
c = make_counter()
print(c(), c())
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: