Topic 37 of 58
Closures
Overview
A closure occurs when a nested (inner) function remembers and has access to the variables of its outer function, even AFTER the outer function has finished executing and returned. This happens because the inner function 'closes over' the local variables it needs. Closures provide a powerful way to implement data hiding and state persistence without the overhead of creating a full-blown Object-Oriented Class.
Syntax
python
def multiplier_factory(factor):
# 'factor' is a local variable to multiplier_factory
def multiply(number):
# The inner function remembers 'factor' forever
return number * factor
return multiply # Return the function object itself, unexecuted
# Create specific, stateful functions
double = multiplier_factory(2)
triple = multiplier_factory(3)
print(double(5)) # 10 (Remembers factor is 2)
print(triple(5)) # 15 (Remembers factor is 3)Common Pitfalls
- The Late Binding trap in loops. Creating closures in a loop (e.g.,
funcs = [lambda: i for i in range(3)]) results in all functions referencing the final value ofi(which is 2). Fix it by forcing early binding:lambda i=i: i.
Interview Questions
Q:
What are the three strict requirements to create a closure in Python?
A:
1. You must have a nested function. 2. The nested function must refer to a value defined in the enclosing function. 3. The enclosing function must return the nested function object.
Real-World Example
Creating a secure, encapsulated bank account without using a Class.
example
python
def open_account(initial_balance):
# This state is hidden and cannot be accessed directly from outside
balance = initial_balance
def withdraw(amount):
nonlocal balance # Required to modify the outer variable
if amount <= balance:
balance -= amount
return f"Success. New balance: {balance}"
return "Insufficient funds"
return withdraw
my_account = open_account(100)
print(my_account(20)) # Success. New balance: 80Check Your Knowledge
Test your understanding of Closures with these quick questions.