This question already has an answer here:
Today I'm reading python change log and meet the nonlocal keyword and did some experiment with it. I find a confusing situation where untriggered assignment will change the nonlocal keyword behavior, please see the example below.
def a():
x = 'a'
def b():
def c():
nonlocal x
x = 'c'
c()
b()
print(x)
a()
>>> python3 test.py
c
def a():
x = 'a'
def b():
def c():
nonlocal x
x = 'c'
c()
if False:
x = 'b'
b()
print(x)
a()
>>> python3 test2.py
a
You can saw that in test2.py, there is an untriggered assginment x = 'b' which changed the behavior of nonlocal.
Why this happened?
Python decides which variables are local to a function at compile time. x is assigned to within the function b, so it's local. That that branch is never actually reached at runtime is irrelevant and can't be decided in general.
So the x in c that is nonlocal is the next x in an outer scope, namely the one in b.
The alternative would be much more surprising -- consider what would happen if the if False: was instead if rand(10) == 6:. Then during the first call of b the nonlocal variable would refer to the outermost one, but randomly at some later call of b it would start referring to the other one!
来源:https://stackoverflow.com/questions/52053204/why-does-untriggered-assignment-changed-nonlocal-behavior