python-namespace
Table of Contents
Python namespace
Python namespace is a mapping from names to objects. Every scope has its own namespace (global, local, built-in), and Python searches them in order using LEGB (Local, Enclosing, Global, Built-in) to find what a name refers to. Understanding scopes prevents variable shadowing bugs and clarifies how closure variables work.
Use locals() and globals() to inspect namespaces, and understand scope rules to debug mysterious variable references.
Example
This example demonstrates namespace scope and variable shadowing.
# run: python3 namespace.py # description: namespace scope and LEGB resolution x = "global" def outer(): x = "enclosing" def inner(): x = "local" print(f"Inner: {x}") print(f"Inner locals: {list(locals().keys())}") inner() print(f"Outer: {x}") outer() print(f"Global: {x}") # Closure and nonlocal def counter(): count = 0 # enclosing scope def increment(): nonlocal count # access enclosing scope count += 1 return count def get(): return count return increment, get inc, get = counter() print(f"\nCounter: {inc()}, {inc()}, {inc()}") print(f"Current: {get()}") # globals() and locals() print(f"\nGlobal 'x': {globals()['x']}") def show_scopes(): y = "local var" print(f"Local namespace keys: {list(locals().keys())}") print(f"y in locals: {'y' in locals()}") print(f"x in globals: {'x' in globals()}") show_scopes()
Common patterns
LEGB lookup order:
- L: Local (function scope)
- E: Enclosing (outer function scope for nested functions)
- G: Global (module scope)
- B: Built-in (built-in functions like
len,print) - Python searches in this order; first match wins
Scope keywords:
global var: access/modify global scope from functionnonlocal var: access/modify enclosing scope from inner function- Without these, assignment creates a new local variable
Closures:
- Inner function captures enclosing scope variables
- Variables must exist at function definition time
- Useful for factories, decorators, callbacks
Inspecting namespaces:
locals(): dict of local namespaceglobals(): dict of global namespacevars(obj): object's attribute namespace (equivalent toobj.__dict__)dir(obj): list of accessible attributes
Common mistakes:
- Forgetting
nonlocaland thinking you're modifying enclosing variable (creates local instead) - Variable shadowing: local
xhides globalxinvisibly - Late binding in closures: inner function captures variable name, not value
- Mutable defaults:
def f(x=[]):modifies same list on each call
Late binding example (common gotcha):
funcs = [] for i in range(3): def f(): return i # captures 'i' by reference, not value funcs.append(f) print([f() for f in funcs]) # [2, 2, 2] not [0, 1, 2]! # Fix: capture value with default arg: def f(i=i):
python-namespace.md · Last modified: by 127.0.0.1
