Course outline · 0% complete

0/27 lessons0%

Course overview →

Closures: functions that remember

lesson 5-1 · ~12 min · 13/27

Quiz

Warm-up from lesson 2-3: what does say = shout (no parentheses) do?

Functions can be built inside functions

Since functions are values, a function can create and return a new function:

def make_multiplier(factor):
    def multiply(n):
        return n * factor
    return multiply

double = make_multiplier(2)
triple = make_multiplier(3)

Here is the surprising part. make_multiplier has already finished by the time you call double(10), yet multiply still knows its factor. An inner function that keeps access to variables from the function that created it is called a closure. Each call to make_multiplier captures its own factor, so double and triple do not interfere.

Closures are not an academic curiosity. They are the machinery behind decorators (next lesson), behind callbacks that need to carry context with them, and behind every "configure once, call many times" function factory in production code.

Code exercise · python

Run this program. Two closures, two remembered factors, zero shared state.

Mutable state in a closure

A closure can also carry state that changes between calls. To reassign a captured variable you must declare it nonlocal, otherwise Python would treat the assignment as a brand-new local variable:

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

Each counter made by make_counter has private, independent state, like a tiny object without a class. Closures are the engine behind decorators in the next lesson, so make sure this example feels solid before moving on.

Code exercise · python

Your turn. Write make_greeter(greeting) that returns a function taking a name and returning "greeting, name!". Create the two greeters and produce the output shown.

Quiz

c1 = make_counter() and c2 = make_counter(). After c1(), c1(), c2(), what does c2 return?

Quiz

Inside make_counter, what happens if you delete the nonlocal line but keep count += 1?