Scope and LEGB
Mar 29, 2026
In This Chapter
- How Python resolves names with the LEGB rule
- The difference between local, enclosing, global, and built-in scope
- When
globalandnonlocalare needed - Why assignment can trigger
UnboundLocalError - Common scope mistakes that show up in interviews
The LEGB Rule
When Python looks up a name, it searches in this order:
- Local
- Enclosing
- Global
- Built-in
That search order is usually called LEGB .
x = "global"
def outer():
x = "enclosing"
def inner():
x = "local"
return x
return inner()Inside inner(), Python finds the local x first, so it never needs to look outward.
Local, Enclosing, Global, Built-in
len = "oops" # shadows the built-in len
def outer():
count = 10
def inner():
return count
return inner()- Local : names defined inside the current function
- Enclosing : names from an outer function
- Global : names defined at module level
- Built-in : names Python provides, like
len,sum,print
Shadowing is legal, but it often hurts readability.
Why Assignment Changes Scope
If Python sees assignment inside a function, it treats that name as local to that function unless told otherwise:
count = 0
def bump():
count += 1This raises UnboundLocalError because Python decides count is local, but it gets read before it is assigned.
global
Use global when you intentionally want to rebind a module-level variable:
count = 0
def bump():
global count
count += 1This works, but in production code mutating globals is usually a smell. Returning values or using objects is often cleaner.
nonlocal
Use nonlocal when you want to rebind a variable from an enclosing function:
def counter():
n = 0
def inc():
nonlocal n
n += 1
return n
return incWithout nonlocal, assignment would create a new local n inside inc().
Interview Traps
- Shadowing built-ins like
list,dict, orlen - Forgetting that assignment makes a name local
- Using
globalwhen a return value would be simpler - Confusing closure capture with
nonlocal
Key Questions
Q: What does LEGB stand for in Python?
It stands for Local, Enclosing, Global, and Built-in. That is the order Python uses for name lookup.
Q: What is the difference between
globalandnonlocal?
global rebinds a module-level name. nonlocal rebinds a name from the nearest enclosing function scope.
Q: Why can assignment inside a function cause
UnboundLocalError?
Because Python treats that name as local for the whole function body once it sees an assignment. If the code reads the name before the local assignment happens, it fails.
Q: Are globals always bad?
Not always, but they increase hidden coupling. For interview answers, say globals are sometimes fine for constants or module-wide state, but mutating them freely usually makes code harder to reason about.
Q: What is variable shadowing?
Shadowing means reusing a name from an outer scope or from a built-in name. It is allowed, but it often makes code harder to read and debug.