这可能是一个简单的范围问题。以下Python文件(模块)中的代码让我有点困惑:

if __name__ == '__main__':
    x = 1
    
print x

在我使用过的其他语言中,这段代码会抛出异常,因为x变量是if语句的局部变量,不应该存在于if语句之外。但是这段代码执行并输出1。有人能解释一下这种行为吗?在一个模块中创建的所有变量对整个模块都是全局的/可用的吗?


当前回答

您正在从命令行执行这段代码,因此,如果conditions为真且设置了x。比较:

>>> if False:
    y = 42


>>> y
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    y
NameError: name 'y' is not defined

其他回答

是的,它们在同一个“局部作用域”中,实际上这样的代码在Python中很常见:

if condition:
  x = 'something'
else:
  x = 'something else'

use(x)

注意,x没有在条件之前声明或初始化,就像在C或Java中那样。

换句话说,Python没有块级作用域。但是,在使用诸如

if False:
    x = 3
print(x)

这显然会引发NameError异常。

是的。对于范围也是如此。当然不是函数。

在你的例子中:如果if语句中的条件为false, x将不会被定义。

与C等语言不同,Python变量在它出现的整个函数(或类或模块)的范围内,而不仅仅是在最里面的“块”中。这就好像你在函数(或类,或模块)的顶部声明了int x,只是在Python中你不需要声明变量。

注意,变量x的存在只在运行时检查——也就是说,当你得到print x语句时。如果__name__不等于"__main__",那么你会得到一个异常:NameError: name 'x'没有定义。

您正在从命令行执行这段代码,因此,如果conditions为真且设置了x。比较:

>>> if False:
    y = 42


>>> y
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    y
NameError: name 'y' is not defined

Python变量的作用域是它们被赋值的最里面的函数、类或模块。像if和while这样的控制块不算数,所以在if中赋值的变量仍然是函数、类或模块的作用域。

(由生成器表达式或list/set/dict推导式定义的隐式函数也算数,lambda表达式也是如此。你不能把赋值语句塞进这些语句中,但lambda形参和for子句目标是隐式赋值。)