If you need help reviewing Nonlocal, take a look at these resources:
Each question has a "Toggle Solution" button -- click it to reveal that question's solution.
Conceptual Questions
Question 1
Would this code work? If not, how would you fix it?
def make_counter():
count = 0
def counter():
count += 1
return count
return counter
No, this code would not work. Here's how we can find out:
- The line
count += 1is equivalent tocount = count + 1, so we rewrite it as such. - Python notices that
countappears on the left side of an assignment statement, so Python remembers to treatcountas a local variable. - Python then begins executing the line. To compute
count + 1Python must look upcount. - But Python had previously marked
countas a local variable, and it doesn't have a value yet! So Python raises an error.
To fix it, add a nonlocal statement:
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
Question 2
Consider the following code:
def fn1(bob):
def fn2(alice):
def fn3(alice):
def fn4():
nonlocal bob, alice
return bob + alice
return fn4
return fn3
return fn2
Answer the following questions:
- In which function's frame does Python start looking for
alice? - In which function's frame does Python stop looking for
alice? - In which function's frame does Python start looking for
bob? - In which function's frame does Python stop looking for
bob?
fn3fn3fn3fn1
Question 3
Identify all the errors regarding nonlocal in the following code:
bob = 2
def fn1(bob):
eve = 3
def fn2(alice):
nonlocal bob, alice
eve = 4
return eve + alice
return fn2
nonlocal alice is incorrect, since
alice is already defined in the same frame (as a
parameter to fn2).
eve = 4 will NOT cause any errors,
since eve is not being referenced before
assignment. However, because eve is not declared
as nonlocal, the eve in fn1 will retain
the value of 3.
Environment Diagrams
Question 4
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
counter = make_counter()
counter()
counter()
Question 5
def foo():
lst = []
def bar(m):
nonlocal lst
lst = lst + [m]
return lst
return bar
bar = foo()
bar(3)
bar(4)
Question 6
def foo():
lst = []
def bar(m):
lst.append(m)
return lst
return bar
bar = foo()
bar(3)
bar(4)