DEV Community

Samiksha Srivastav
Samiksha Srivastav

Posted on

Understanding Scope and Closures in Python

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)