A closure is a nested function that retains access to variables from its enclosing lexical scope even after the outer function has finished executing.
flowchart LR
subgraph Enclosing Function Scope
var["cell reference: rate = 0.15"]
end
subgraph Returned Inner Function
closure["closure_fn(amount)"]
end
closure -->|__closure__| var
from typing import Callable
def create_tax_calculator(tax_rate: float) -> Callable[[float], float]:
"""Factory function generating closure tax calculators."""
# Enclosing variable 'tax_rate' is captured in the closure
def calculate_tax(amount: float) -> float:
return round(amount * tax_rate, 2)
return calculate_tax
def create_accumulator(initial_value: int = 0) -> Callable[[int], int]:
"""Closure maintaining mutable state via 'nonlocal'."""
state = initial_value
def add(value: int) -> int:
nonlocal state # Mutate captured enclosing variable
state += value
return state
return add
if __name__ == "__main__":
vat_calculator = create_tax_calculator(0.20)
sales_tax_calculator = create_tax_calculator(0.07)
print(f"VAT on $100: ${vat_calculator(100.0)}")
print(f"Sales Tax on $100: ${sales_tax_calculator(100.0)}")
counter = create_accumulator(10)
print("Accumulator +5:", counter(5)) # 15
print("Accumulator +20:", counter(20)) # 35
[lambda: i for i in range(5)] binds i=4 for all lambdas!).functools.partial for Simple Currying: For simple function argument binding without mutable state, prefer functools.partial.fn.__closure__[0].cell_contents.Write a function make_multiplier(n: int) returning a closure function that multiplies its input parameter by n.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With