You’ll be able to
- Create functions that remember variables from their enclosing scope
- Use closures to build small, stateful helpers
- Distinguish closures from classes with
__call__ - Avoid the late-binding gotcha with default arguments
Loading lesson…
Why this matters
Every decorator, every functools.partial, and every FastAPI dependency-injection callable is a closure under the hood. Understanding late binding versus early binding is why senior engineers write def f(x, _cached=expensive()) and why lambda i: i inside a loop is a classic bug in JavaScript-to-Python converts.
Common pitfalls
- Late-binding in loops —
[lambda: i for i in range(3)]all return 2; uselambda i=i: ito capture eagerly. - Rebinding an outer variable without
nonlocal— Python creates a new local and the closure appears broken. - Leaking large objects in closure cells — a captured DataFrame keeps memory alive; use
weakrefor explicitdel.