Python resolves names using the LEGB rule: Local → Enclosing → Global → Built-in.
| File | Description |
|---|---|
example.py |
global, nonlocal, and nested scope demos |
A counter factory where each instance maintains its own count using nonlocal.
def make_counter(start=0):
count = start
def increment(step=1):
nonlocal count # modify enclosing scope, not create local
count += step
return count
def get_count():
return count
return increment, get_count
inc, get = make_counter(100)
print(inc()) # 101
print(inc()) # 102
print(get()) # 102x = "global"
def outer():
x = "enclosing"
def inner():
print(x) # finds "enclosing" (Enclosing scope)
inner()
outer()Without nonlocal, x = ... inside inner would create a new local variable, not modify the enclosing one.
Q1: What is the LEGB rule?
A: Python searches names in order: Local (current function), Enclosing (outer functions), Global (module), Built-in (preloaded names like len, print).
Q2: What does global x do?
A: Declares that assignments to x inside the function modify the module-level variable, not create a local one.
Q3: What does nonlocal x do?
A: Declares that assignments modify the nearest enclosing (non-global) scope. Used in nested functions and closures.
Q4: What is UnboundLocalError?
A: Occurs when you assign to a name in a function (making it local) but read it before assignment. Python treats any assignment as making the name local for the entire function.
Q5: Does my_list.append(x) need global my_list?
A: No. You're mutating the object, not rebinding the name. global is only needed when you assign to the name itself: my_list = [].
Q6: What is a closure's enclosing scope?
A: The scope of the outer function where the inner function was defined — not where it was called.
python3 example.py