What does "nonlocal" do in Python 3?
closures, global, nested-function, python, python-nonlocal
Solution
Compare this, without using `nonlocal`:
x = 0
def outer():
x = 1
def inner():
x = 2
print("inner:", x)
inner()
print("outer:", x)
outer()
print("global:", x)
# inner: 2
# outer: 1
# global: 0
To this, using `nonlocal`, where `inner()`'s `x` is now also `outer()`'s `x`:
x = 0
def outer():
x = 1
def inner():
nonlocal x
x = 2
print("inner:", x)
inner()
print("outer:", x)
outer()
print("global:", x)
# inner: 2
# outer: 2
# global: 0
If we were to use `global`, it would bind `x` to the properly "global" value:
x = 0
def outer():
x = 1
def inner():
global x
x = 2
print("inner:", x)
inner()
print("outer:", x)
outer()
print("global:", x)
# inner: 2
# outer: 1
# global: 2
Problem
What does `nonlocal` do in Python 3.x? To close debugging questions where OP needs `nonlocal` and doesn't realize it, please use Is it possible to modify variable in python that is in outer, but not global, scope? instead. Although Python 2 is officially unsupported as of January 1, 2020, if for some reason you are forced to maintain a Python 2.x codebase and need an equivalent to `nonlocal`, see nonlocal keyword in Python 2.x.