From the Google Style Guide on lexical scoping:
A nested Python function can refer to variables defined in enclosing functions, but can not assign to them.
Both of these seem to check out at first:
# Reference
def toplevel():
a = 5
def nested():
print(a + 2)
nested()
return a
toplevel()
7
Out[]: 5
# Assignment
def toplevel():
a = 5
def nested():
a = 7 # a is still 5, can't modify enclosing scope variable
nested()
return a
toplevel()
Out[]: 5
So why, then, does a combination of both reference and assignment in the nested function lead to an exception?
# Reference and assignment
def toplevel():
a = 5
def nested():
print(a + 2)
a = 7
nested()
return a
toplevel()
# UnboundLocalError: local variable 'a' referenced before assignment