问题:在if语句中初始化的变量的作用域是什么?

我是Python的新手,所以这可能是一个简单的范围界定问题。Python文件(模块)中的以下代码使我有些困惑:

if __name__ == '__main__':
    x = 1

print x

在我使用过的其他语言中,此代码将引发异常,因为该x变量是if语句的局部变量,不应在其外部存在。但是此代码将执行并打印1。任何人都可以解释此行为吗?是否在模块中创建的所有变量都是全局的/可用于整个模块?

I’m new to Python, so this is probably a simple scoping question. The following code in a Python file (module) is confusing me slightly:

if __name__ == '__main__':
    x = 1

print x

In other languages I’ve worked in, this code would throw an exception, as the x variable is local to the if statement and should not exist outside of it. But this code executes, and prints 1. Can anyone explain this behavior? Are all variables created in a module global/available to the entire module?


回答 0

Python变量的作用域是分配给它们的最里面的函数,类或模块。控制块(如ifwhile块)不计在内,因此在内分配的变量的if作用域仍限于函数,类或模块。

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

Python variables are scoped to the innermost function, class, or module in which they’re assigned. Control blocks like if and while blocks don’t count, so a variable assigned inside an if is still scoped to a function, class, or module.

(Implicit functions defined by a generator expression or list/set/dict comprehension do count, as do lambda expressions. You can’t stuff an assignment statement into any of those, but lambda parameters and for clause targets are implicit assignment.)


回答 1

是的,它们在同一个“本地范围”中,实际上这样的代码在Python中很常见:

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

use(x)

请注意,x不会在条件之前声明或初始化它,例如在C或Java中。

换句话说,Python没有块级作用域。不过,请注意以下示例

if False:
    x = 3
print(x)

这显然会引发NameErrorexceptions。

Yes, they’re in the same “local scope”, and actually code like this is common in Python:

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

use(x)

Note that x isn’t declared or initialized before the condition, like it would be in C or Java, for example.

In other words, Python does not have block-level scopes. Be careful, though, with examples such as

if False:
    x = 3
print(x)

which would clearly raise a NameError exception.


回答 2

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

  • 搜索本地范围

  • 搜索所有封闭函数的范围

  • 搜索全球范围

  • 搜索内置

来源

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

Scope in python follows this order:

  • Search the local scope

  • Search the scope of any enclosing functions

  • Search the global scope

  • Search the built-ins

(source)

Notice that if and other looping/branching constructs are not listed – only classes, functions, and modules provide scope in Python, so anything declared in an if block has the same scope as anything decleared outside the block. Variables aren’t checked at compile time, which is why other languages throw an exception. In python, so long as the variable exists at the time you require it, no exception will be thrown.


回答 3

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

int x;
if(something)
    x = 1;
else
    x = 2;

但在Python中声明是隐式的,因此当您分配给x时,它会自动声明。这是因为Python是动态类型的-它无法在静态类型的语言中工作,因为取决于所使用的路径,可能会在未声明的情况下使用变量。这将在编译时以静态类型的语言捕获,但是允许使用动态类型的语言。

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

As Eli said, Python doesn’t require variable declaration. In C you would say:

int x;
if(something)
    x = 1;
else
    x = 2;

but in Python declaration is implicit, so when you assign to x it is automatically declared. It’s because Python is dynamically typed – it wouldn’t work in a statically typed language, because depending on the path used, a variable might be used without being declared. This would be caught at compile time in a statically typed language, but with a dynamically typed language it’s allowed.

The only reason that a statically typed language is limited to having to declare variables outside of if statements in because of this problem. Embrace the dynamic!


回答 4

与C之类的语言不同,Python变量在它所出现的整个函数(或类,模块)的范围内,而不仅仅是在最内部的“块”中。就像您int x在函数(或类,模块)的顶部声明的一样,只是在Python中不必声明变量。

请注意,x仅在运行时(即,进入print x语句时)检查变量的存在。如果__name__不相等"__main__",则会出现异常:NameError: name 'x' is not defined

Unlike languages such as C, a Python variable is in scope for the whole of the function (or class, or module) where it appears, not just in the innermost “block”. It is as though you declared int x at the top of the function (or class, or module), except that in Python you don’t have to declare variables.

Note that the existence of the variable x is checked only at runtime — that is, when you get to the print x statement. If __name__ didn’t equal "__main__" then you would get an exception: NameError: name 'x' is not defined.


回答 5

是。for范围也是如此。但是当然不起作用。

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

Yes. It is also true for for scope. But not functions of course.

In your example: if the condition in the if statement is false, x will not be defined though.


回答 6

您是从命令行执行此代码的,因此if条件为true且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

you’re executing this code from command line therefore if conditions is true and x is set. Compare:

>>> if False:
    y = 42


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

回答 7

请注意,由于仅在运行时检查Python类型,因此您可以使用如下代码:

if True:
    x = 2
    y = 4
else:
    x = "One"
    y = "Two"
print(x + y)

但是我很难考虑由于类型问题而导致代码无错误运行的其他方式。

And note that since Python types are only checked at runtime you can have code like:

if True:
    x = 2
    y = 4
else:
    x = "One"
    y = "Two"
print(x + y)

But I’m having trouble thinking of other ways in which the code would operate without an error because of type issues.


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。