Search⌘ K
AI Features

Closures and Inner Functions

Explore how Python treats functions as objects and how inner functions can access outer variables to create closures. Understand how closures preserve local state between function calls and support configurable, maintainable code avoiding globals.

We usually expect variables created inside a function to disappear when the function returns. However, certain problems require us to retain data across multiple calls without resorting to global variables.

To solve this, we leverage the fact that Python functions are objects. This means we can create functions dynamically, return them as results, and attach data to them; a powerful feature known as a closure.

Functions as objects

Before we can build closures, we must understand that Python treats functions exactly like any other object, such as an integer or a string. A function is not just a set of instructions; it is a value that can be assigned to variables, passed as an argument, and returned from other functions.

When we use def, we create a function object. We can inspect this object or assign it to a new name.

Python 3.14.0
def shout(text):
return text.upper() + "!"
# Assign the function object 'shout' to a new variable 'yell'
yell = shout
# Pass the function object as an argument to another function
def process_text(func, text):
return func(text)
# We pass 'yell' (the function), not 'yell()' (the result)
result = process_text(yell, "hello functions")
print(result)
  • Line 5: We create an alias for the function by assigning shout to yell. This demonstrates that the function name shout is just a label pointing to a block of code in memory, and yell now points to that exact same block.

  • Line 12: We pass yell into ...