🧩 Functions, lesson 7 of 8
Closures and decorators
Build functions that remember variables, and wrap functions with decorators.
12 min
1 exercise
2 quizzes
0/3 solved
Getting Python ready… examples can run in a moment.
A function can be defined inside another function. The inner function can use the outer function's variables, and it keeps them even after the outer function has returned. A function together with the variables it uses is a closure.
A greeter factory
make_greeter returns greet itself, without calling it. hi and hola each remember their own greeting.
Inside a function, reading an outer variable works.
Assigning to it does not: count += 1 makes a new
local count, as you saw in the scope lesson. To
rebind a variable from the enclosing function, declare
it with nonlocal. (global would mean a
module-level variable instead.)
A counter that remembers
bump keeps count between calls. Remove the nonlocal line and the code fails.
What does this print?
A decorator is a function that takes a function and returns a wrapped version of it. The wrapper usually calls the original and adds something before or after. Here is one written by hand:
Shout, by hand
greet is unchanged. loud_greet is the wrapper: it calls greet and shouts the result.
The @ shorthand
@shout on the line above the def means exactly greet = shout(greet). The @property and @dataclass you'll meet in the OOP module, and @lru_cache in the algorithms module, are decorators too.
What does this print?
Counter and doubler
Two parts:
- Write
make_counter(). It returns a function that returns the next number each time it is called: 1, 2, 3, ... Every counter keeps its own count. Usenonlocal. - Write a decorator
doubled(func). It returns a wrapper that callsfuncwith the same arguments and returns twice the result. The wrapper must accept any number of arguments.