Closures

1 minute read

Cover Page

Closures

In Python, closures are a way to capture and remember the environment in which a function was created, even after the outer function has finished executing. A closure allows the inner function to access variables from the outer function’s scope.

Key Features of Closures:

  1. Nested Functions: Closures involve an inner function that is defined inside an outer function.
  2. Access to Non-Local Variables: The inner function retains access to variables in the outer function’s scope even after the outer function has returned.
  3. Function Object: The inner function is returned as a function object.

Example Walkthrough:

def outer_function(x):
    # This is a non-local variable for the inner function.
    y = 10

    def inner_function(z):
        # Accessing variables x and y from outer scope.
        return x + y + z
    return inner_function
  1. When outer_function(5) is called:

    • x = 5 is captured from the argument.
    • y = 10 is defined within the outer scope.
  2. The inner function inner_function is returned as an object, but it remembers: The value of x = 5 and y = 10 (even though outer_function has finished execution).

  3. When the returned inner_function is called, it can still access x and y:

my_closure = outer_function(5)
print(my_closure(3))  # Output: 18 (5 + 10 + 3)

How Python Implements Closures:

  1. The outer function’s local variables that are referenced by the inner function are stored in the closure attribute of the inner function.

  2. This is what allows the inner function to “remember” variables from its enclosing scope.

Checking the Closure:

Every function has a closure attribute that holds references to these variables.

def outer(a):
    b = 10
    def inner(c):
        return a + b + c
    return inner

closure_func = outer(5)
# Tuple of cell objects
# output: (<cell at 0x7a4e3c561420: int object at 0x7a4e3d1ca888>,
# <cell at 0x7a4e3c561450: int object at 0x7a4e3d1ca928>)
print(closure_func.__closure__)
 # output: [5, 10]
print([cell.cell_contents for cell in closure_func.__closure__])
  • __closure__: Stores references to variables from the enclosing scope.
  • Each cell in __closure__ corresponds to a captured variable.

Conclusion

Closures are a powerful feature in Python that enable the creation of functions with encapsulated behavior and state. By capturing variables from their enclosing scope, closures provide an elegant way to implement functionality like decorators, callbacks, memoization, and more.

Leave a comment