在if语句中初始化变量的范围是什么?

fro*_*die 247 python variables scope if-statement local-variables

我是Python的新手,所以这可能是一个简单的范围问题.Python文件(模块)中的以下代码让我感到困惑:

if __name__ == '__main__':
    x = 1

print x
Run Code Online (Sandbox Code Playgroud)

在我工作过的其他语言中,这段代码会引发异常,因为x变量是if语句的本地变量,不应该存在于它之外.但是这段代码执行并打印1.任何人都可以解释这种行为吗?模块中创建的所有变量是全局/可用于整个模块吗?

Luk*_*rer 264

Python变量的范围限定在分配它们的最内层函数,类或模块中.类似于ifwhile块的控制块不计数,因此在一个内部分配的变量if仍然限定为函数,类或模块.

(由生成器表达式或list/set/dict理解定义的隐式函数确实计算,lambda表达式也是如此.您不能将赋值语句填充到其中任何一个,但lambda参数和for子句目标是隐式赋值.)

  • 感谢您的回答。我已经用 python 编码很多年了,直到现在才明白这一点。知道这一点确实会让事情变得更容易。我总是发现 python 处理作用域的方式有时是有问题的。 (7认同)
  • @chandr3sh https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces (2认同)

Eli*_*sky 85

是的,它们处于相同的"本地范围",实际上这样的代码在Python中很常见:

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

use(x)
Run Code Online (Sandbox Code Playgroud)

请注意,x在条件之前未声明或初始化,例如,在C或Java中.

换句话说,Python没有块级范围.但是要小心,例如

if False:
    x = 3
print(x)
Run Code Online (Sandbox Code Playgroud)

这显然会引发NameError例外.

  • 我陷入了“if False:”陷阱。 (4认同)

Dan*_*l G 37

python中的作用域遵循以下顺序:

  • 搜索本地范围

  • 搜索任何封闭函数的范围

  • 搜索全局范围

  • 搜索内置插件

(来源)

请注意,if并未列出其他循环/分支构造 - 只有类,函数和模块在Python中提供了作用域,因此if块中声明的任何内容与块外部的任何内容都具有相同的作用域.在编译时不检查变量,这就是其他语言抛出异常的原因.在python中,只要变量在您需要时存在,就不会抛出任何异常.


Ski*_*ick 9

正如Eli所说,Python不需要变量声明.在C中你会说:

int x;
if(something)
    x = 1;
else
    x = 2;
Run Code Online (Sandbox Code Playgroud)

但是在Python声明是隐式的,所以当你赋给x时它会自动声明.这是因为Python是动态类型的 - 它不能在静态类型语言中工作,因为根据使用的路径,可以使用变量而不声明.这将在编译时以静态类型语言捕获,但使用动态类型语言是允许的.

if由于此问题,静态类型语言仅限于必须在语句之外声明变量的唯一原因.拥抱动感!


Pau*_*son 9

与C之类的语言不同,Python变量在其出现的整个函数(或类或模块)的范围内,而不仅仅在最里面的"块"中.就好像你int x在函数(或类或模块)的顶部声明,除了在Python中你不必声明变量.

请注意,x仅在运行时检查变量的存在- 也就是说,当您到达print x语句时.如果__name__不相等"__main__"那么你会得到一个例外:NameError: name 'x' is not defined.


Oli*_*ier 7

是的。对于范围来说也是如此for。但当然不是函数。

在您的示例中:如果语句中的条件if为假,x则不会被定义。