今天,我正在阅读python更改日志并遇到nonlocal关键字,并对其进行了一些实验。我发现一种令人困惑的情况,即未经触发的分配会更改nonlocal
关键字的行为,请参见下面的示例。
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
您可以看到,在test2.py
中,有一个未触发的组合x = 'b'
改变了非本地的行为。
为什么会这样?
答案 0 :(得分:3)
Python会在编译时确定哪些变量是函数的局部变量。 x
被分配到函数b
中,因此它是本地的。在运行时从未真正到达该分支是无关紧要的,并且通常无法确定。
因此x
中非本地的c
是外部作用域中的下一个x
,即b
中的那个。
替代方案将更加令人惊讶-考虑如果将if False:
改为if rand(10) == 6:
会发生什么。然后,在b
的第一次调用期间,非局部变量将引用最外层的变量,但是在以后的某个b
调用中,它将随机地引用另一个变量!