Scoping: The LEGB Rule
Expert Answer & Key Takeaways
Mastering Scoping: The LEGB Rule is essential for high-fidelity technical performance and advanced exam competency in 2026.
Scoping & Namespaces: The LEGB Rule and Local/Global Internals (2026)
Python resolves variable names using the LEGB (Local, Enclosing, Global, Built-in) rule, implemented via hierarchical namespace dictionaries that determine object visibility and lifetime.
1. The Proof Code (Closure Internals)
import dis
def outer_function(x: int):
# Enclosing scope
def inner_function(y: int):
# Local scope accessing 'free variable' x
return x + y
return inner_function
closure_func = outer_function(10)
def inspect_closure() -> None:
print(f"Result: {closure_func(5)}")
# Inspecting the 'cell' that stores the free variable
print(f"Free variables: {closure_func.__code__.co_freevars}")
print(f"Cell value: {closure_func.__closure__[0].cell_contents}")
if __name__ == "__main__":
inspect_closure()
print("\nBytecode for inner_function:")
dis.dis(closure_func)
# Output:
# Result: 15
# Free variables: ('x',)
# Cell value: 10
# Bytecode shows: LOAD_DEREF 0 (x)2. Execution Breakdown
- Namespaces as Dictionaries: A namespace is literally a Python dictionary.
globals()returns the dictionary for the module scope, whilelocals()returns the dictionary for the current function execution. - Lexical Scoping: Python determines the scope of every variable at compile-time. If you assign to a name anywhere in a function, Python marks that name as 'Local' for the entire function, regardless of the assignment order.
- Free Variables: In a nested function, a variable that is referenced but not defined locally is a 'free variable'. Python stores these in a special
__closure__attribute to ensure they persist even after the outer function finishes. - LEGB Search Order: When Python sees a name, it searches: Local -> Enclosing -> Global -> Built-in. If not found in any, it raises a
NameError.
3. Detailed Theory
The efficiency of name resolution depends on which scope the variable resides in.
LOAD_FAST vs. LOAD_GLOBAL
In CPython, local variables are optimized. The compiler knows exactly how many locals a function has and stores them in a fixed-size array. Accessing them uses the
LOAD_FAST opcode, which is an array index lookup (very fast). Global and Built-in lookups use LOAD_GLOBAL, which requires a dictionary hash table lookup (slower).The UnboundLocalError Trap
Consider this common bug:
x = 10
def fail():
print(x)
x = 20 # Compilation marks 'x' as localExecuting
fail() raises UnboundLocalError because Python decided x was local during compilation, but at runtime, the print(x) happens before the local x has been assigned a value.Modifying Scopes
- global: Forces a name to be resolved in the module-level dictionary.
- nonlocal: Forces a name to be resolved in the nearest enclosing (outer function) scope, enabling stateful closures.
[!TIP] Senior Secret: To optimize performance-critical loops that call global functions (likemath.sin), bind the global function to a local variable first:sin = math.sin. This converts multipleLOAD_GLOBALlookups into fasterLOAD_FASTlookups inside the loop.
Top Interview Questions
?Interview Question
Q:What is a 'free variable' in the context of Python closures?
A:
A free variable is a variable referenced in a code block (like a nested function) that is not defined there. For a closure, these variables are captured from the enclosing scope and stored in the function's
__closure__ attribute.?Interview Question
Q:Why is local variable access faster than global variable access?
A:
Local variables are stored in a fixed-size array and accessed via index (
LOAD_FAST). Global variables are stored in a dictionary and require a hash table lookup (LOAD_GLOBAL), which involves more CPU instructions.?Interview Question
Q:What happens if you modify a 'locals()' dictionary inside a function?
A:
Modifying the dictionary returned by
locals() generally has no effect on the actual local variables. Python updates this dictionary from the internal stack/array, but it does not read changes back from the dictionary into the local variables.Course4All Engineering Team
Verified ExpertData Science & Backend Engineers
The Python curriculum is designed by backend specialists and data engineers to cover everything from basic logic to advanced automation and API design.
Pattern: 2026 Ready
Updated: Weekly
Found an issue or have a suggestion?
Help us improve! Report bugs or suggest new features on our Telegram group.