When Python resolves a name inside a function, it searches four scopes in order: local, enclosing function, global, and built-ins. It stops at the first match. Outside a function, only global and built-in scopes participate; indentation alone does not create a new scope. section 6.5
The four levels answer different lookup questions:
- Local: was the name assigned inside the current function? section 6.5
- Enclosing function: did a surrounding function define the name? section 6.12
- Global: does the module-level namespace contain the name? section 6.5
- Built-ins: does Python provide the name, such as int or sum? section 6.5
Shadowing a built-in
sum = 0 for i in range(5): sum += i print(sum) print(sum([10, 20, 30])) # TypeError: 'int' object is not callable The global integer named sum is found before the built-in sum function, so it shadows the callable. section 6.5
Enclosing state in a closure
def foo(x): def bar(y): return x * y return bar f = foo(10) print(f(20)) # 200 bar finds x in its enclosing function. Each call to foo can return a function carrying a separate enclosing value. section 6.12 section 6.5
Visualizes separate password-generating closures and the enclosing state retained by each returned function. section 6.12


