Course Content
Python Essentials for AI Engineer
6 sections · 48 lessons
What is variable scope?
What you need to know
LEGB in action
Python
1x = "global"23def outer():4 x = "enclosing"5 def inner():6 return x # not local -> found in the enclosing scope7 return inner()89print(outer()) # enclosing10print(x) # global -> outer's x never touched this one11print(len("abc")) # 3 -> 'len' found in the built-in scopeAssignment makes a name local
Python decides which names are local when it compiles the function, not line by line. If a name is assigned anywhere in the function, it is local everywhere in that function:
Python
1count = 02def bump():3 count += 1 # reads local 'count' before it has a value4try:5 bump()6except UnboundLocalError as e:7 print(e) # cannot access local variable 'count' where it is not associated with a valueBlocks do not create scopes
Python
1for i in range(3):2 last = i3print(i, last) # 2 2 -> both still exist after the loop45squares = [n * n for n in range(3)]6# print(n) -> NameError: comprehensions DO have their own scopeClosures
An inner function that uses a variable from an enclosing function "closes over" it and keeps it alive after the outer function returns. This is how decorators and function factories work.
A real-life example
A notebook shadows a built-in, a very common Jupyter bug:
Python
1scores = [0.91, 0.87, 0.95]2max = max(scores) # shadows the built-in max() in the global scope3print(max) # 0.9545try:6 best_latency = max([120, 95, 210])7except TypeError as e:8 print(e) # 'float' object is not callable9del max # removes the global name; built-in is visible again10print(max([120, 95, 210])) # 210Because of LEGB, the global max is found before the built-in one. The cell that fails can be fifty cells below the one that caused it. Name variables max_score, total, ids — never max, sum, list, id, input or type.
Follow-up questions to expect
- "What is
UnboundLocalError?" — Reading a local variable before it is assigned. It usually means you assigned to a name you meant to read from an outer scope. - "What does
nonlocaldo?" — It lets an inner function rebind a variable from its enclosing function, the wayglobaldoes for module variables. - "Do comprehensions leak their loop variable?" — Not in Python 3; they have their own scope. Plain
forloops do leak.