从未执行赋值时的Python作用域

从未执行赋值时的Python作用域,python,scope,Python,Scope,所以我明白了 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从未发生过,我应该

所以我明白了

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:赋值前引用的局部变量“x”


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缺少声明,并且允许名称绑定操作发生在代码块中的任何位置。代码块的局部变量可以通过扫描块的整个文本进行名称绑定操作来确定。

谢谢您的回答!我知道如何使它与全局一起工作,我只想知道python究竟为什么会这样做。请查看文档或python范围基于LEGB(本地、封闭、全局和内置),有很多文章解释它是如何工作的。也许从这里开始:这能回答你的问题吗?