Exercises — global and nonlocal keywords
1.2.31 · D4· Coding › Introduction to Programming (Python) › global and nonlocal keywords

Shuru karne se pehle, woh do rules dobara yaad karo jo sab kuch decide karte hain:
Har ek ko pehle paper par karo, PHIR solution kholo. Yahi self-test page ka poora point hai.
Level 1 — Recognition
(Kya tum spot kar sakte ho ki kaunsa naam kaunse scope mein rehta hai, aur keyword ki zaroorat bhi hai ya nahi?)
L1.1
Har line ke liye batao ki global/nonlocal needed hai ya not needed, aur kyun.
total = 0
def a(): print(total) # (i)
def b(): total = 5 # (ii) -- want to change the module total
def c(): mylist.append(3) # (iii) -- mylist is a module list
def d(): total = total + 1 # (iv) -- want to change module totalRecall Solution L1.1
- (i) not needed. Hum sirf
totalread kar rahe hain. Rule R ladder climb karta hai: koi localtotalnahi mila, toh global mil jaata hai. Reading ke liye kabhi keyword ki zaroorat nahi. - (ii) needed →
global total. Humtotalassign kar rahe hain. Rule A se ek bilkul naya localtotal = 5ban jaata hai aur module wala chhoota rehta hai. Module variable change karne ke liyeglobal totaldeclare karna padega. - (iii) not needed.
mylist.append(3)ek mutation hai object ki, naammylistki rebinding nahi. Koimylist = ...nahi hai, isliye Rule A kabhi fire nahi hota. Dekho Mutable vs Immutable objects. - (iv) needed →
global total. (ii) se bhi zyada bura: yahan right-hand sidetotalread karta hai, lekin Rule A ne usse already local mark kar diya hai, toh read ko local-with-no-value milta hai → UnboundLocalError.global totaldono sides ko fix karta hai.
L1.2
Har reference ke liye scope level batao (L, E, G, ya B):
len_ = len # (i) len
name = "top"
def outer():
name = "mid"
def inner():
print(name) # (ii) name
print(len) # (iii) len
inner()Recall Solution L1.2
- (i)
B(Built-in).lenlocally, kisi enclosing func mein, ya module level par define nahi hai → yeh Built-in scope se aata hai. (Yeh LEGB ki aakhiri rung hai.) - (ii)
E(Enclosing).innerke paas koi localnamenahi; nearest enclosing functionouterke paasname = "mid"hai, toh yehmidprint karta hai. Yeh wahan rok leta hai — yeh module waale"top"tak chadhta nahi. - (iii)
B(Built-in). Koi local, enclosing, ya globallennahi, toh phir se Built-in.
Level 2 — Application
(Printed output predict karo.)
L2.1
x = 10
def f():
global x
x = x + 5
f()
f()
print(x)Recall Solution L2.1 — prints
20
global x Rule A ko cancel karta hai: x f mein har jagah module variable hai. Start x = 10. Pehla call: 10 + 5 = 15. Doosra call: 15 + 5 = 20. Print 20.
L2.2
def make_adder(step):
total = 0
def add():
nonlocal total
total += step
return total
return add
g = make_adder(3)
print(g(), g(), g())Recall Solution L2.2 — prints
3 6 9
add ek closure hai make_adder ke locals total aur step par. nonlocal total add ki assignment ko enclosing total ("next-door box") ki taraf point karta hai, jo calls ke beech survive karta hai. step = 3.
Calls: 0+3=3, 3+3=6, 6+3=9 → prints 3 6 9.
L2.3
count = 100
def outer():
count = 1
def inner():
global count
count = count + 1
inner()
return count
print(outer(), count)Recall Solution L2.3 — prints
1 101
Dhyaan se trace karo — yeh classic global-vs-nonlocal confusion hai:
innerglobal countkehta hai, toh yeh modulecount(100) edit karta hai,outerka localcount(1) nahi. Module101ho jaata hai.outerapna KHUD ka localcountreturn karta hai, jo kabhi touch nahi hua →1.- Toh
outer()→1, aur modulecount→101. Prints1 101.
Level 3 — Analysis
(Bug dhoondo aur exact mechanism explain karo.)
L3.1
Yeh 1 print karna chahiye, lekin crash hota hai. Kaun sa error aur kyun?
n = 0
def tick():
n += 1
print(n)
tick()Recall Solution L3.1 —
UnboundLocalError
n += 1 matlab n = n + 1 hai, ek assignment. Rule A n ko tick ke liye poori tarah local stamp karta hai. Right-hand side phir local n read karta hai, jiske paas abhi koi value nahi → UnboundLocalError: local variable 'n' referenced before assignment. Dekho UnboundLocalError.
Fix: tick ki pehli line mein global n add karo, taaki n dono sides par module variable refer kare.
L3.2
Yeh SyntaxError raise karta hai. nonlocal ko kuch kyun nahi milta?
def f():
def g():
nonlocal k
k = 5
g()
f()Recall Solution L3.2 —
SyntaxError: no binding for nonlocal 'k' found
nonlocal ke liye ek already-existing variable chahiye enclosing function scope mein bind karne ke liye. f mein koi k define nahi hai, toh g ka nonlocal k point karne ke liye koi enclosing k nahi hai. global ke unlike (jo module-level naam create kar deta hai), nonlocal compile time par hi mana kar deta hai.
Fix: g se pehle f ke andar k = 0 define karo.
L3.3
append kyun kaam karta hai lekin = fail karta hai?
data = []
def add_ok():
data.append(1) # works
def add_bad():
data = data + [1] # crashesRecall Solution L3.3
add_ok:data.append(1)kabhidata = ...nahi likhta. Yeh sirf us list object ko mutate karta hai jis par naam already point karta hai. Koi assignment nahi ⇒ Rule A kabhi fire nahi hota ⇒dataglobal wala rehta hai ⇒ works.add_bad:data = data + [1]naamdatako rebind karta hai. Rule Adatako local banata hai; right-hand side not-yet-assigned local read karta hai →UnboundLocalError. Fix:global data, ya behtar, mutate karo:data.append(1). Dekho Mutable vs Immutable objects.
Level 4 — Synthesis
(Spec match karne ke liye code design ya repair karo.)
L4.1
Ek bank() factory banao jo do functions return kare deposit(amount) aur balance(). deposit running balance mein add kare; balance() usse return kare. Koi global variables allowed nahi.
Recall Solution L4.1
def bank():
money = 0
def deposit(amount):
nonlocal money # rebinding the enclosing 'money'
money += amount
def balance():
return money # only reading -> no keyword needed
return deposit, balance
d, b = bank()
d(100); d(50)
print(b()) # 150money bank mein rehta hai. deposit usse rebind karta hai → nonlocal chahiye. balance sirf usse read karta hai → kuch nahi chahiye (Rule R enclosing scope tak chadh jaata hai). Dono closures ek hi money box share karte hain, toh deposits balance ko visible hote hain. Result: 150.
L4.2
Isko repair karo taaki yeh pehle enclosing_changed phir global_original print kare.
x = "global_original"
def outer():
x = "enclosing_original"
def inner():
global x # (bug is here)
x = "enclosing_changed"
inner()
print(x)
outer()
print(x)Recall Solution L4.2
Jaise likha hai, global x inner ko module x edit karwata hai → module "enclosing_changed" ho jaata hai, lekin outer ka local x chhoota rehta hai, toh woh "enclosing_original" phir "enclosing_changed" print karta hai — spec ka ulta.
Fix: global x ko nonlocal x se badlo:
def inner():
nonlocal x
x = "enclosing_changed"Ab inner outer ka x rebind karta hai → outer "enclosing_changed" print karta hai; module x kabhi touch nahi hota → "global_original" print hota hai. ✓
Level 5 — Mastery
(Multiple interacting scopes ke saath full traces.)
L5.1
Charon printed lines predict karo.
v = "G"
def outer():
v = "E"
def mid():
nonlocal v
v = "E2"
def inner():
global v
v = "G2"
inner()
print(v) # (1)
mid()
print(v) # (2)
outer()
print(v) # (3)Recall Solution L5.1 — prints
E2, E2, G2
Do alag boxes track karo: module v aur outer's v.
mid:nonlocal v→outerkevse bind; usse"E2"set karta hai.inner:global v→ modulevse bind; usse"G2"set karta hai. Yehouterkevko touch nahi karta.- (1) par
print(v)midke andar hai, jiskav=outerkav="E2". - (2) par
print(v)outerke andar hai, uskav="E2". - (3) par
print(v)module level par hai ="G2". Output:E2,E2,G2.
L5.2
Yeh loop teen functions banane ke liye hai jo 0, 1, 2 return kare. Explain karo actually kya hota hai aur isko default argument se fix karo (ek scope insight).
funcs = []
for i in range(3):
def f():
return i
funcs.append(f)
print([g() for g in funcs])Recall Solution L5.2 — actually prints
[2, 2, 2]
Har f ek closure hai jo enclosing scope (yahan module) se i read karta hai call time par, creation time par nahi. Jab tak hum unhe call karte hain, loop khatam ho chuka hota hai aur i == 2, toh teeno 2 return karte hain.
Fix — default argument se abhi value capture karo:
funcs = []
for i in range(3):
def f(i=i): # default is evaluated NOW, binding a fresh local i
return i
funcs.append(f)
print([g() for g in funcs]) # [0, 1, 2]Default argument def time par evaluate hota hai aur per-function store hota hai, toh har f ka apna frozen i hota hai. Result: [0, 1, 2].
Recall Self-check: kaun sa keyword? (one-line drills)
Top-level function ke andar se module-level counter ko rebind karna ::: global
Closure ke enclosing function mein rehne wale variable ko rebind karna ::: nonlocal
Global list par .append() call karna ::: neither (mutation, rebinding nahi)
Outer variable ko print() karna jise tum kabhi assign nahi karte ::: neither (pure read)
x = x + 1 jahan x sirf module top par define hai ::: global (warna UnboundLocalError)
Connections
- global and nonlocal keywords
- Scope and LEGB rule
- Functions in Python
- Closures
- Mutable vs Immutable objects
- UnboundLocalError
- Pure functions and side effects