← Python lessons

Python First-Class Functions and Closures

Python has first-class functions: you can store, pass and return functions. A closure lets an inner function keep access to an enclosing function's variables.

Read Defining functions first.

Store and pass a function

Use a function's name without parentheses to pass the function itself. Parentheses call it.

def double(number):
    return number * 2

def apply(operation, value):
    return operation(value)

operation = double
print(operation(4))
print(apply(double, 5))

The stored function returns 8. Passing it to apply() gives 10.

Return a closure

An inner function can use variables from the enclosing function after that outer call finishes.

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

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

These closures keep access to separate factor variables, printing 10 and 15.

Update an enclosing variable with nonlocal

Use nonlocal to reassign an enclosing function's variable. Reading that variable needs no declaration.

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

counter = make_counter()
print(counter())
print(counter())

The same closure remembers the count and prints 1, then 2.

Note: Closures read enclosing variables when called; they do not freeze their values. Functions created in a loop can therefore share the loop variable's final value.

See also: Lambda functions, Decorators.

Your turn

Create a closure that adds 10, then call it with 3 and print the result.

def make_adder(amount):
    def add(number):
        return number + amount
    return add

# add two lines: create add_ten with make_adder(10), then print add_ten(3)

Expected output

13

Practise this in the free Python course, where every exercise checks your code instantly.