Namespaces & Scope¶
A namespace is a mapping between names (identifiers) and objects. Every time you create a variable, function, or class, Python stores that name inside a namespace — and namespaces are exactly what let the same name exist in different places without colliding.
Both variables are named x, but Python knows exactly which one to use because they live in different namespaces.
What is Scope?¶
Scope determines where a namespace is accessible — where Python looks when it needs to resolve a name.
The first print() reads the local x inside foo(). The second reads the global x outside it.
Types of Namespaces¶
Python has four namespaces.
Local Namespace¶
Created every time a function runs, and destroyed when it returns.
Enclosing Namespace¶
Created when one function is nested inside another.
x belongs to outer()'s namespace. inner() doesn't have its own x, so Python looks one level out and finds it there.
Global Namespace¶
Holds anything defined outside every function, and lives for the entire life of the program.
Built-in Namespace¶
Holds everything Python ships with — print(), len(), sum(), list(), dict(), int(), and the rest — all available without importing a thing.
The LEGB Rule¶
Python resolves a name by searching, in order:
and stops the moment it finds a match.
inner() has its own x, so the search stops right there — the enclosing, global, and built-in namespaces never even get checked.
Take away the local x:
Now inner() has no x of its own, so Python steps out one level and finds it in outer()'s namespace — still without ever reaching global.
And with no local or enclosing x at all:
This time the search runs all the way out to the global namespace before it finds a match. And if a name isn't defined anywhere in your code at all:
Python falls all the way through to the built-in namespace, where len() lives.
The global Keyword¶
Assigning to a variable inside a function normally creates a local variable, even if a global one shares the name:
This leaves the global x untouched. To actually modify it, say so explicitly:
The nonlocal Keyword¶
nonlocal does the same thing one level out — it lets a nested function modify a variable in its enclosing namespace instead of shadowing it.
Without nonlocal, inner() would just create its own local x and leave outer()'s copy untouched.
globals() and locals()¶
globals() returns the global namespace as a dictionary:
locals() does the same for whatever namespace you're currently in:
Examples¶
Example 1¶
Output:
Example 2¶
Output:
Example 3¶
Output:
Follow-up Questions¶
What is a namespace?¶
A mapping between names and objects.
What is scope?¶
Where a namespace is accessible — where Python looks when resolving a name.
What are the four namespaces in Python?¶
Local, Enclosing, Global, and Built-in.
What is the LEGB rule?¶
The order Python searches for a name: Local, then Enclosing, then Global, then Built-in — stopping at the first match.
What does the global keyword do?¶
Lets a function modify a variable in the global namespace instead of creating a local shadow.
What does nonlocal do?¶
Lets a nested function modify a variable in its enclosing namespace.
What does locals() return?¶
A dictionary of the current local namespace.
What does globals() return?¶
A dictionary of the global namespace.
Common Interview Mistakes¶
❌ Thinking namespaces are memory locations.
✔ A namespace is a mapping between names and objects, not a place in memory.
❌ Confusing scope with namespace.
✔ A namespace stores names; scope determines where those names are visible.
❌ Forgetting the order of LEGB.
✔ Local → Enclosing → Global → Built-in.
❌ Thinking global and nonlocal are the same.
✔ global reaches the global namespace; nonlocal reaches the enclosing one.
Key Takeaways¶
- A namespace is a mapping between names and objects.
- Scope determines where Python searches for a name.
- Python has four namespaces: Local, Enclosing, Global, and Built-in.
- Name resolution follows the LEGB rule, and stops at the first match.
globalmodifies a variable in the global namespace;nonlocalmodifies one in the enclosing namespace.globals()andlocals()expose the current namespaces as dictionaries.