# Nonlocal: basic-level questions

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 += 1` is equivalent to `count = count + 1`, so we rewrite it as such.
• Python notices that `count` appears on the left side of an assignment statement, so Python remembers to treat `count` as a local variable.
• Python then begins executing the line. To compute `count + 1` Python must look up `count`.
• But Python had previously marked `count` as 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``````

1. In which function's frame does Python start looking for `alice`?
2. In which function's frame does Python stop looking for `alice`?
3. In which function's frame does Python start looking for `bob`?
4. In which function's frame does Python stop looking for `bob`?
1. `fn3`
2. `fn3`
3. `fn3`
4. `fn1`

### 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)``````