1.2.30Introduction to Programming (Python)

Variable scope — LEGB rule (Local, Enclosing, Global, Built-in)

1,912 words9 min readdifficulty · medium1 backlinks

WHY does scope even exist?

WHAT is "scope"? The region of code where a name is visible/usable. WHAT is a "namespace"? The actual dictionary mapping names → objects that backs a scope.


The four scopes (the rooms Python searches)

Figure — Variable scope — LEGB rule (Local, Enclosing, Global, Built-in)

HOW lookup works — trace it like Python does


The crucial twist: assignment creates a LOCAL name

Fixing it: global and nonlocal


Read vs. write — the rule that unifies it all

Operation What Python does
Read x Search L → E → G → B, first hit wins
Write x = … (no keyword) Always creates/uses Local
Write with global x Targets Global
Write with nonlocal x Targets Enclosing

Recall Feynman: explain to a 12-year-old

Imagine you ask "Where are my shoes?" You check your room first (Local), then your big brother's room (Enclosing), then the front hallway (Global), and finally the shoe shop that always has shoes (Built-in). You grab the first pair you find and stop looking. But there's a trick: if you ever say "I'll put shoes HERE in my room" (shoes = ...), Python assumes the shoes are in your room for the whole day — so if you try to wear them before putting them there, you're standing barefoot and confused (that's the UnboundLocalError). Saying global is like telling everyone "I mean the hallway shoes, not mine."


Active Recall

LEGB stands for
Local, Enclosing, Global, Built-in — the order Python searches a name when reading it.
First-match rule in LEGB
Python uses the FIRST scope (in L→E→G→B order) that contains the name and stops searching.
Which scope is searched first
Local (the current function's own assigned names).
Which scope is searched last
Built-in (e.g. len, print, range, sum).
Why does x = x + 1 cause UnboundLocalError for a global x
The assignment makes x local for the whole function, so reading x before it's assigned fails; Python never consults the global.
What does global x do
Tells the function that x refers to the module-level (Global) name, so assignments rebind the global.
What does nonlocal x do
Binds x to the nearest ENCLOSING function's variable; assignments edit that, and the variable must already exist.
Difference between global and nonlocal
global targets module scope (G); nonlocal targets the enclosing function scope (E).
Do for/if blocks create scope in Python
No — only functions, modules, and comprehensions create scope; names there belong to the enclosing function/module.
What is shadowing a built-in
Defining a name (e.g. len) at L/E/G level so Python finds it before the built-in, hiding the original.
Reading vs writing rule
Reading searches L→E→G→B; writing (without keyword) always creates/uses a Local name.

Connections

  • Functions and Parameters — scope is created by function calls.
  • Closures and Nested Functions — rely on the Enclosing scope (E).
  • Namespaces and the dict model — scopes are backed by dictionaries.
  • Mutable vs Immutable arguments — mutating a list inside a function ≠ rebinding it.
  • NameError and UnboundLocalError — direct consequences of LEGB.
  • Modules and importimport populates the Global namespace.

Concept Map

backed by

solves

resolves

first match wins

no match

shadows

forces name to

read before assign

Scope: region where name visible

Namespace: dict name to object

Name collisions across functions

LEGB lookup order

Reading a name

Local: current function

Enclosing: outer function

Global: module top level

Built-in: len, print, range

Stops searching

NameError

Assignment name equals ...

UnboundLocalError

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, jab Python kisi variable ka naam padhta hai — maan lo x — to wo har jagah randomly nahi dhoondta. Uska ek fixed order hota hai: pehle Local (jis function ke andar ho), phir Enclosing (bahar wala function, agar nested ho), phir Global (file ke top level ke naam), aur last me Built-in (jaise len, print). Jis room me naam pehle mil jaaye, bas wahi use hota hai — Python aage dhoondna band kar deta hai. Isko yaad rakhne ka short form hai LEGB.

Sabse important twist yahi hai: LEGB sirf padhne (read) ke liye hai. Jaise hi function ke andar kahin bhi x = kuch likha, Python decide kar leta hai ki poore function me x ab Local hai. Isiliye count = count + 1 likhne par agar count global tha, to bhi UnboundLocalError aata hai — kyunki Python soch raha hai ki count local hai aur abhi tak usme kuch assign hua hi nahi.

Is problem ko theek karne ke liye do keywords hain. global count bolne se Python samajh jaata hai ki "bhai, yahan count matlab module wala global count, naya local mat banao." Aur nonlocal n bolne se enclosing (bahar wale) function ka n edit hota hai — ye closures me kaam aata hai. Yaad rakho: global = module scope (G), nonlocal = enclosing function (E). Dono alag hain.

Ek aur galat-fehmi clear kar lo: Python me for aur if blocks apna alag scope nahi banate (C/Java se ulta). Sirf functions, modules, aur comprehensions scope banate hain. Isliye for loop ke andar banaya variable bahar bhi accessible rehta hai. Ye chhoti baatein interviews aur bugs dono me bahut help karti hain.

Go deeper — visual, from zero

Test yourself — Introduction to Programming (Python)

Connections