Visual walkthrough — Variable scope — LEGB rule (Local, Enclosing, Global, Built-in)
1.2.30 · D2· Coding › Introduction to Programming (Python) › Variable scope — LEGB rule (Local, Enclosing, Global, Built-
Hum parent LEGB note ko extend kar rahe hain. Agar koi word yahan unfamiliar lage, toh woh wahan se aaya tha — lekin hum sab kuch zero se rebuild karte hain anyway.
Step 0 — Vocabulary, picture ke saath (taaki koi symbol earn na kiya ho)
Kisi bhi search se pehle, hume teen simple words chahiye, har ek ek picture ke saath pin ki gayi.

Upar ke figure mein: pale-yellow drawer Built-in namespace hai (Python ise tumhare program shuru hone se pehle bharta hai — len, print, range yahan rehte hain). Blue drawer tumhari file ka Global namespace hai. Pink drawers har baar naye bante hain jab koi function run karta hai. Arrows woh ek hi direction dikhate hain jisme Python search karne ki permission hai: pehle andar waale drawers, baad mein bahar waale. Woh kabhi "neeche" kisi aisi function mein search nahi kar sakta jisme woh abhi hai nahi.
Yeh direction kyun aur ulti kyun nahi? Kyunki scope ka poora point (parent note: "private workspace") yeh hai ki function ke private names door walon par jeetne chahiye. Inside-out search guarantee karta hai ki sabse paas wala, sabse specific name pehle milta hai.
Step 1 — Woh program jo hum trace karenge
Yeh woh ek example hai jo hum baaki poore page ke liye dekhenge. Ise padho, abhi apne dimaag mein run mat karo — hum woh saath milke karenge.
KYA hai hamare paas: wahi naam x teen baar likha gaya, teen alag drawers mein.
KYUN yeh perfect specimen hai: sirf search order decide karta hai ki print(x) kaunsa dekhega. Kuch aur vary nahi karta.
PICTURE: agle steps ise drawer by drawer kholte hain.
Step 2 — Drawers banao us order mein jisme Python unhe banata hai
Python saare namespaces ek saath nahi banata. Woh unhe banata hai jab code run hota hai.

KYA figure dikhata hai: ek timeline. Pehle Built-in drawer pehle se maujood hai (yellow). Phir file load hoti hai aur x = "GLOBAL" ek note Global drawer (blue) mein daalta hai. Phir outer() call hoti hai, jo Enclosing drawer (pink, outer) spawn karti hai x = "ENCLOSING" ke saath. Phir inner() call hoti hai, innermost drawer (pink, inner) spawn karti hai x = "LOCAL" ke saath.
KYUN order matter karta hai: ek drawer tabhi exist karta hai jab iska function run ho raha ho. Jab inner khatam hoti hai, iska drawer fek diya jaata hai. Isi liye locals private aur temporary hote hain.
Step 3 — Search: print(x) inner ke andar fire hota hai
Ab sach ka waqt. Python print(x) hit karta hai aur naam x resolve karna padta hai. Woh drawers mein L → E → G → B chalata hai, pehle khulne waale darwaze par rukta hai.

KYA red arrow karta hai: woh innermost pink drawer (L) se shuru karta hai, poochta hai "kya tumhare paas x hai?", darwaza khulta hai (x = "LOCAL"), search turant rok deta hai.
KYUN woh kabhi E, G, ya B tak nahi pahunchta: first-match rule. Jab ek baar koi drawer "haan" kehta hai, Python woh value le leta hai aur quit kar deta hai. Enclosing "ENCLOSING" aur Global "GLOBAL" abhi bhi wahan hain — unhe bas kabhi consult nahi kiya jata.
Yeh line left se right padhne par: Python L mein jaata hai, x milta hai, aur E, G, B par slashes matlab "kabhi nahi gaya." Output: LOCAL.
Step 4 — Ek drawer ka note hatao, arrow aage jaate dekho
Ab local line delete karo taaki inner ab x assign na kare:
def inner():
print(x) # ab koi local x nahi
KYA figure dikhata hai: red arrow L tak pahunchta hai, drawer x ke liye khaali milta hai, toh woh baahir E ki taraf jaata hai. Outer ke drawer mein x = "ENCLOSING" hai — darwaza khulta hai, search rukti hai.
KYUN yeh rule ki poori power hai: program text nahi badla sivar ek deleted line ke, phir bhi answer LOCAL se ENCLOSING ho jaata hai. Search order ne akele decide kiya.
Agar hum outer ka x bhi hata dete, arrow E se G tak sail kar jaata aur "GLOBAL" print karta. Woh bhi hatao, toh B tak pahunchta hai — lekin x ek built-in nahi hai, toh arrow last drawer se gir jaata hai aur Python NameError raise karta hai. Dekho NameError and UnboundLocalError.
Step 5 — Woh degenerate case jo sabko fool karta hai: UnboundLocalError
Yeh woh case hai jo parent note ne "crucial twist" ke roop mein flag kiya tha. Hum ise ek puri picture dete hain kyunki yeh logon ki intuition todo deta hai.

KYA hota hai: bump ek bhi line run karne se pehle, Python compile time par poori function body scan karta hai aur count = ... dekhta hai. Woh ek assignment count ko poori function ke liye Local stamp kar deti hai — top se bottom tak.
KYUN crash hota hai: line count = count + 1 par, right side count + 1 ko count read karna padta hai. Lekin count ab Local hai, aur Local drawer mein abhi koi value nahi hai (write abhi hua nahi). Python yahan Global par fall back karne se mana hai — assignment ki presence ne naam ko L par lock kar diya.
PICTURE: figure mein count ka Local drawer ek khali box with a question mark ke roop mein draw kiya gaya hai, aur read-arrow isse ek red "STOP — UnboundLocalError" mein bounce karta hai. Zaruri baat: arrow ko Global drawer par jaane ki ijazat nahi hai, chahe count = 0 wahan seedha baitha ho.
Step 6 — Do escape hatches, side by side draw ki gayi
Fix yeh hai ki Python ko batao ki assignment ek baahri drawer ko target karni chahiye naaki naaya local banana chahiye.

KYA figure dikhata hai: do functions.
- Left:
global countassignment arrow ko seedha blue Global drawer tak redirect karta hai. - Right:
nonlocal narrow ko nearest pink Enclosing drawer (outer kan) tak redirect karta hai, global par nahi.
count = 0
def bump():
global count
count = count + 1 # Global ko rebind karta hai
bump(); print(count) # 1
def outer():
n = 0
def inner():
nonlocal n
n += 1 # outer ka n rebind karta hai
inner(); inner()
return n
print(outer()) # 2KYUN har keyword exist karta hai:
global xkehta hai "is poori function ke liye,xmatlab module-level naam hai — local mat banao." Khaali-local trap gayab ho jaata hai kyunki koi local hai hi nahi.nonlocal xkehta hai "xmatlab nearest enclosing function kax" — exactly woh tool jo Closures and Nested Functions ko calls ke beech state yaad rakhne aur update karne deta hai.
Step 7 — Shadowing edge case (global ne built-in kha liya)
Ek aur scenario jo reader ko kabhi surprise nahi karna chahiye: kya hoga agar tum kisi variable ka naam kisi built-in jaisa rakhdo?
len = 5 # G mein ab 'len' hai
print(len("hi")) # TypeError: 'int' object is not callableKYA hua: jab Python len resolve karta hai, woh L → E → G → B search karta hai. Lekin ab G mein len = 5 hai, aur G ko B se pehle search kiya jaata hai. Toh len integer 5 ban jaata hai, aur 5("hi") nonsense hai → TypeError.
KYUN yeh NameError nahi hai: naam mila tha — bas galat drawer mein. Shadowing matlab hai ek paas wala drawer door waale ko chhupaata hai. Built-in len B mein abhi bhi exist karta hai; woh bas tab tak unreachable hai jab tak G ka note uske saamne baitha hai. G se len delete karo (del len) aur built-in phir se visible ho jaata hai.
Ek-picture summary

Yeh final board poora walkthrough compress karta hai: char nested drawers, ek read-arrow jo L→E→G→B travel karta hai aur pehli hit par rukta hai, aur teen coloured write-arrows jo dikhate hain ki =, global, aur nonlocal value kahan deposit karte hain. Red "STOP" tags woh do tarike mark karte hain jisme lookup mar sakti hai: end se gir jaana (NameError) ya khaali local read karna (UnboundLocalError).
Recall Feynman retelling — simple words mein poora walkthrough
Tum chahte ho naam x ke peeche ki value. Tum apne khud ke room (Local) se shuru karte ho. Agar tumhari x sticky-note wahan hai, tum use le lete ho aur ruk jaate ho — tum doosre darwaze kabhi kholte bhi nahi. Agar tumhare room mein koi x nahi, tum baahir apne bade bhai/behen ke room (Enclosing) mein jaate ho, phir front hallway (Global) mein, phir aakhir mein woh dukaan jo hamesha stocked rehti hai (Built-in). Jo pehla x milta hai woh jeetta hai.
Ab woh trap: agar tumhare room mein kahin bhi tumne x rakhne ka vaada kiya hai (x = ...), Python x ko tumhare poore visit ke liye tumhare room mein rehne wala treat karta hai. Toh agar tum use actually rakhne se pehle grab karne ki koshish karo, tumhara haath hawa mein band ho jaata hai — yahi UnboundLocalError hai, aur Python hallway mein jhankne se inkaar karta hai tumhe bachane ke liye. global x kehna woh vaada cancel kar deta hai aur tumhe seedha hallway ki taraf point karta hai; nonlocal x kehna tumhe tumhare bhai/behen ke room ki taraf point karta hai. Aur agar tum hallway mein kabhi len ka note chhor do, sab log tumhara note dukaan ke note se pehle dhundhte hain — toh asli len gayab ho jaata hai jab tak tum apna note nahi faado.
Active Recall
Read-arrow ka search order
Step 3 mein print(x) LOCAL kyun print karta hai
x inner ke Local drawer mein milta hai, toh search E, G, ya B tak pahunchne se pehle hi ruk jaati hai.UnboundLocalError ki wajah
global x kya redirect karta hai
nonlocal x kya redirect karta hai
len shadow karne se kaunsa error aata hai
len tumhari Global value (jaise ek int) se resolve hoti hai jo callable nahi hai; naam MILA tha, bas galat drawer mein.Jab koi drawer naam nahi rakhta toh kya error aata hai
Connections
- Parent topic — LEGB rule
- Functions and Parameters — har call ek naaya Local drawer spawn karta hai.
- Closures and Nested Functions — isi liye Enclosing drawer (E) exist karta hai.
- Namespaces and the dict model — in figures ke har drawer literally ek
dicthai. - Mutable vs Immutable arguments — drawer mein naam ko mutate karna vs. rebind karna.
- NameError and UnboundLocalError — summary figure mein do "STOP" tags.
- Modules and import —
importnames ko Global (blue) drawer mein daalta hai.