I was comfortable with Python scopes pretty quickly.
But when I reached closures, my first reaction was:
“How is this even possible?”
An inner function remembering variables after the outer function has already finished execution felt really confusing at first.
But after understanding how Python handles memory and scope internally, closures finally became much easier to understand.
So here’s the explanation that helped me the most.
First, What is Scope?
Scope simply means:
“Where can a variable be accessed from?”
Python mainly works with different scopes like:
- Global scope
- Local scope
- Enclosing scope
Let’s see a simple example:
Here:
- x can be accessed almost everywhere because it is global
- y only exists inside the function
Once the function finishes execution, y disappears from memory.
That part is straightforward.
Now Comes Closures
Closures become interesting when:
- a function exists inside another function
- and the inner function uses variables from the outer function
Example:
At first glance, this might look normal.
But something very important is happening here.
What happens?
- outer() starts execution
- x = 10 is created
- inner() function is created
- inner gets returned
Normally, after a function finishes execution, its local variables should disappear.
So technically: x should have been destroyed.
the inner() function is still using x
So instead of deleting it, Python preserves that variable in memory.
Even though outer() has already finished execution.
How?
Because the inner function remembered the variable from its outer function.
And this is exactly what a closure is.
Simple Definition of Closure
A closure is:
A function that remembers variables from its outer scope even after the outer function has finished execution.
Or even more simply:
Closure = Function + Remembered Environment
Why This Feels Special
Normally, local variables disappear after function execution ends.
But in closures:
- Python keeps those variables alive
- because another function still needs them
That’s the “magic” behind closures.
Let's take a real example - Counter
This example can make closures finally click for us:
and output is:
1
2
3
What’s Happening Here?
Every time increment() runs:
- it still remembers the old value of count
- even though counter() already finished execution long ago
That remembered state is preserved because of closure.
And: nonlocal allows us to modify that outer variable.
Important Confusion
Not every nested function is a closure.
A closure only exists when:
the inner function remembers variables from the outer function.
Why Closures Matter
Closures are heavily used in:
- decorators
- callbacks
- state management
- function factories
Even many advanced Python features internally depend on this concept.
End Game
At first, closures looked very confusing to me because the outer function had already finished execution.
But once I understood that Python preserves variables in memory when inner functions still need them, the concept became much clearer.
It’s one of those topics that feels “magical” initially, but very logical once broken down step by step.



Top comments (0)