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