Scope and the Call Stack
Scope is the region of code where a name is visible. A variable created inside a function is local: it exists only while the function runs and vanishes when it returns.
def make_total():
subtotal = 10 # local to make_total
return subtotal
make_total()
# print(subtotal) # NameError: subtotal does not exist out hereEach call gets its own fresh set of local variables. Two functions can both use a variable named x without interfering, because each x lives in its own scope. When one function calls another, Python stacks these frames up (the call stack) and unwinds them as each return happens.
A function can read a variable from the outer (global) scope, but assigning to a name inside a function creates a new local by default. This catches everyone:
count = 0
def bump():
count = count + 1 # error: count looks local here but has no value yet
# bump() # raises UnboundLocalErrorYou can force it with the global keyword, but resist the urge. Functions that quietly reach out and change global state are hard to test and full of surprises. The clean pattern is to take values in as parameters and hand results back with return:
def bump(count):
return count + 1
count = 0
count = bump(count) # explicit, predictable
print(count) # 1Prefer parameters and return values over globals. Your future self will thank you.
Avoid globals. Define a function increment that takes one parameter count and returns count + 1. Do not use the global keyword and do not read any outside variable. The function must work purely from its parameter, so increment(0) returns 1 and increment(41) returns 42.
This lesson is locked
Lessons open one at a time. Finish the previous lesson to unlock this one.