Closures in Python

Python supports anonymous functions, which are also known as lambda functions. These can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.

def int_seq():
    i = 0
    def inner():
        nonlocal i
        i += 1
        return i
    return inner

def main():
    # We call int_seq, assigning the result (a function)
    # to next_int. This function value captures its
    # own i value, which will be updated each time
    # we call next_int.
    next_int = int_seq()

    # See the effect of the closure by calling next_int
    # a few times.
    print(next_int())
    print(next_int())
    print(next_int())

    # To confirm that the state is unique to that
    # particular function, create and test a new one.
    new_ints = int_seq()
    print(new_ints())

if __name__ == "__main__":
    main()

This Python code demonstrates the concept of closures. The int_seq function returns another function, which we define inside the body of int_seq. The returned function closes over the variable i to form a closure.

To run the program:

$ python closures.py
1
2
3
1

In Python, we use the nonlocal keyword to indicate that a variable should be accessed from an enclosing scope, not including the global scope. This is similar to how the closure in the original example captures and modifies the i variable.

The last feature of functions we’ll look at for now is recursion, which is also supported in Python.