0:00 Hook — Python remembers dead variables
0:40 The LEGB scope rule — how Python finds names
2:30 Local vs Global — the two most common scopes
4:00 nonlocal — reach into enclosing scope
5:30 What IS a closure? — function + captured cells
7:00 Inspecting _closure_ — see the memory live
8:30 Factory functions — make_multiplier, make_validator
10:00 The loop closure trap — the #1 beginner mistake
11:30 Closure vs Class — which to choose and when
12:30 Real patterns — memoize, counter, partial apply
13:30 Mini project — event handler system
15:00 Challenge + Summary
🎯 What You'll Learn
1. The LEGB Scope Rule
Local — inside the current function
Enclosing — outer functions (closures live here)
Global — module level
Built-in — Python's core functions
The exact order Python searches for every name
2. Local vs Global Scope
Reading globals = free, no keyword
Modifying globals = requires global keyword
Why global is considered bad practice
Better alternatives: return values and closures
3. The nonlocal Keyword
Read enclosing variables = free, no keyword
Modify enclosing variables = requires nonlocal
Side-by-side comparison: without vs with nonlocal
The UnboundLocalError trap
4. What IS a Closure?
Definition: inner function + captured environment
Closure survives even after outer function returns
count variable stays alive because increment captured it
Each call creates isolated state — no sharing
5. 🔥 Live Memory Inspection (Unique Scene)
Inspect _closure_ — tuple of cell objects
cell_contents — the actual captured value
__code__.co_freevars — names of captured variables
No other Python channel shows this — watch it live!
6. Factory Functions
make_multiplier(factor) — creates specialized multipliers
make_validator(lo, hi) — creates range validators
make_power(exp) — creates power functions
One definition → infinite specialised variants
7. The Loop Closure Trap
90% of beginners fall for this
All lambdas capture the same variable, not the value
After the loop: all return the last value
3 fixes:
Default argument
Factory function
List comprehension with default
8. Closure vs Class — Decision Guide
Use Closure Use Class
✅ 1 callable ✅ Multiple methods
✅ Simple state ✅ Complex lifecycle
✅ Throwaway/one-off ✅ Inheritance needed
✅ Decorators, callbacks ✅ Data models, services
9. Real-World Closure Patterns
Memoize — hand-rolled cache decorator
Counter with reset — publisher-subscriber pattern
Partial application — own implementation of functools.partial
Used in Flask, Django, asyncio, and every modern framework
10. Mini Project — Event Handler System
text
on() — register handler
emit() — fire event, run all handlers
off() — unregister handler
Three closures sharing one handlers list — closures + *args + factory pattern together.
🏗️ Your Challenge
Build a Closure Toolkit:
@once_only — Call function once, cache result, return cached on all later calls
make_accumulator() — Running total + separate reset closure
Fix the loop closure trap — 3 different ways
make_pipeline(*fns) — Pipe input through each function in sequence
Full type hints for ALL functions
mypy --strict — 0 errors required
Paste your solution + mypy output in the comments! I reply to every single one.
🔗 Resources
💻 GitHub Repo: github.com/CodeToAGI/python-course-closures
📚 Official Python Docs: docs.python.org/3/tutorial/controlflow.html
👨💻 About CodeToAGI
CodeToAGI is a daily Python series by Mahaz Abbasi that takes you from Python fundamentals to AGI concepts.
Each episode includes:
📺 In-depth video explanation
💻 Real code examples
🎯 Practical challenges
🔍 Industry patterns used in production
🔔 SUBSCRIBE
Subscribe and hit the bell to never miss an episode → [Subscribe Link]
📱 Follow for updates:
GitHub: github.com/CodeToAGI
💬 Join the Community
Drop your challenge solutions in the comments:
✅ @once_only decorator
✅ make_accumulator() closure
✅ Loop trap fixed 3 ways
✅ make_pipeline() factory
✅ mypy --strict output
I read every single comment and reply to everyone! 🌟