Python 赋值从未执行时的范围

Python scope when assignment never performed

我明白了

x = 5
def f():
    print(x)

f()
print(x)

回馈 5 和 5。

我也明白了

x = 5
def f():
    x = 7
    print(x)

f()
print(x)

返回 7 和 5。

下面有什么问题吗?

x = 5
def f():
    if False:
        x = 7   
        print(x)
    else:
        print(x)

f()
print(x)

我想既然 x=7 从未发生过,我应该再次获得 5 和 5。相反,我得到

UnboundLocalError: local variable 'x' referenced before assignment

是否python将x视为局部变量,因为在这个缩进块中有一个赋值表达式,不管它是否被执行?具体规则是什么?

您需要在函数 f() 中使用 global,如下所示:

x = 5
def f():
    global x
    if False:
        x = 7   
        print(x)
    else:
        print(x)

f()
print(x)

定义函数时,python 将 x 解释为局部变量,因为它是在函数体内分配的。在运行时,当您进入 else 子句时,解释器会查找未分配的 局部变量 x

如果你想让两个x引用同一个变量,你可以在函数体内添加global x,在它赋值之前本质上告诉python当我调用 x 时,我指的是全局范围 x.

如果名称绑定操作发生在代码块中的任何位置,则块中名称的所有使用都将被视为对当前块的引用。当名称在绑定之前在块中使用时,这可能会导致错误。这个规则很微妙。 Python 缺少声明并允许名称绑定操作发生在代码块中的任何位置。代码块的局部变量可以通过扫描块的整个文本进行名称绑定操作来确定。