Python Closures · Exercises
Core Python

Python Closures Exercises

4 exercises that build on the Python Closures lesson, from easy to hard. Each one is checked in your browser when you press Check. Stuck? Use the hint before peeking at the solution.

What this lesson covers: A closure is a function that remembers the variables of the enclosing function where it was created, so it can keep using them even after that outer function has returned. By the end you can build function factories and counters with nonlocal, explain which variables a closure remembers, inspect them with closure, avoid the late-binding loop trap, and decide between a closure and a class. You will practise: Build an adder factory; Predict the late-binding prices; Fix the click counter; A wallet with two functions.

0 / 4 completed

Python Closures practice exercises

1. Build an adder factory

Write code Easy

Write a function make_adder(amount) that returns a new function. The returned function takes one number and returns that number plus amount. Then create add_ten = make_adder(10) and print add_ten(5).

Your code
def make_adder(amount):
    # define an inner function that adds amount, and return it
    pass

add_ten = make_adder(10)
print(add_ten(5))

2. Predict the late-binding prices

Predict the output Medium

Two lists of functions are built in a loop. One list uses plain lambdas, the other freezes the value with a default argument. After the loop the variable discount is changed once more. Type exactly what the program prints.

Read this code
def make_prices():
    shown = []
    frozen = []
    for discount in [10, 20, 30]:
        shown.append(lambda: 100 - discount)
        frozen.append(lambda discount=discount: 100 - discount)
    discount = 50
    return shown, frozen

shown, frozen = make_prices()
print([f() for f in shown])
print([f() for f in frozen])

3. Fix the click counter

Fix the bug Medium

make_counter(start) should return a function that adds 1 to its count every time it is called, so the program should print 3. Instead it crashes with an UnboundLocalError. Fix the bug without using a global variable.

Your code
def make_counter(start):
    count = start
    def increment():
        count += 1
        return count
    return increment

clicks = make_counter(0)
clicks()
clicks()
print(clicks())

4. A wallet with two functions

Write code Hard

Write make_wallet(balance) that returns two functions as a tuple (spend, remaining), both sharing the same hidden balance:

  • spend(amount) subtracts amount and returns True, unless amount is more than the balance. In that case it changes nothing and returns False.
  • remaining() returns the current balance.

Every call to make_wallet must create an independent wallet. Do not use a class or a global variable. Then create spend, remaining = make_wallet(50), spend 20, and print remaining().

Your code
def make_wallet(balance):
    # two inner functions that share the variable balance
    pass

spend, remaining = make_wallet(50)
spend(20)
print(remaining())

Next lessonPython Decorators

More Python Closures examples · All Python exercises