为什么未触发分配会更改“非本地”行为?

时间:2018-08-28 08:19:16

标签: python python-3.x python-nonlocal

今天,我正在阅读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'改变了非本地的行为。

为什么会这样?

1 个答案:

答案 0 :(得分:3)

Python会在编译时确定哪些变量是函数的局部变量。 x被分配到函数b中,因此它是本地的。在运行时从未真正到达该分支是无关紧要的,并且通常无法确定。

因此x中非本地的c是外部作用域中的下一个x,即b中的那个。

替代方案将更加令人惊讶-考虑如果将if False:改为if rand(10) == 6:会发生什么。然后,在b的第一次调用期间,非局部变量将引用最外层的变量,但是在以后的某个b调用中,它将随机地引用另一个变量!