← Back to Python Course | Chapter 4: Functions | Lesson 9 of 9

Python Closures

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?

python
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

python
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

python
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

python
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

python
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())

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.