问题:Python“ for”循环的作用域

我不是在问Python的作用域规则。我大致了解作用域在Python中用于循环的原理。我的问题是为什么设计决策是以这种方式做出的。例如(无双关语):

for foo in xrange(10):
    bar = 2
print(foo, bar)

上面将打印(9,2)。

这让我感到很奇怪:“ foo”实际上只是在控制循环,而“ bar”是在循环内部定义的。我可以理解为什么可能需要在循环外部访问“ bar”(否则,for循环的功能将非常有限)。我不明白的是为什么循环退出后,控制变量必须保留在范围内。以我的经验,它只会使全局命名空间混乱,并且使查找其他语言的解释器捕获的错误变得更加困难。

I’m not asking about Python’s scoping rules; I understand generally how scoping works in Python for loops. My question is why the design decisions were made in this way. For example (no pun intended):

for foo in xrange(10):
    bar = 2
print(foo, bar)

The above will print (9,2).

This strikes me as weird: ‘foo’ is really just controlling the loop, and ‘bar’ was defined inside the loop. I can understand why it might be necessary for ‘bar’ to be accessible outside the loop (otherwise, for loops would have very limited functionality). What I don’t understand is why it is necessary for the control variable to remain in scope after the loop exits. In my experience, it simply clutters the global namespace and makes it harder to track down errors that would be caught by interpreters in other languages.


回答 0

最可能的答案是,它只是使语法简单,没有成为采用的绊脚石,而且许多人都对在循环结构中分配名称时不必消除名称的范围感到满意。变量不在范围内声明,而是由赋值语句的位置隐含。该global关键字存在只是为了这个原因(象征分配在全球范围内完成)。

更新资料

这里是关于该主题的精彩讨论:http : //mail.python.org/pipermail/python-ideas/2008-October/002109.html

以前的使for循环变量位于循环本地的建议,偶然发现了现有代码的问题,该代码依赖循环变量在退出循环后保持其值,这似乎被认为是理想的功能。

简而言之,您可以将其归咎于Python社区:P

The likeliest answer is that it just keeps the grammar simple, hasn’t been a stumbling block for adoption, and many have been happy with not having to disambiguate the scope to which a name belongs when assigning to it within a loop construct. Variables are not declared within a scope, it is implied by the location of assignment statements. The global keyword exists just for this reason (to signify that assignment is done at a global scope).

Update

Here’s a good discussion on the topic: http://mail.python.org/pipermail/python-ideas/2008-October/002109.html

Previous proposals to make for-loop variables local to the loop have stumbled on the problem of existing code that relies on the loop variable keeping its value after exiting the loop, and it seems that this is regarded as a desirable feature.

In short, you can probably blame it on the Python community :P


回答 1

Python不像其他一些语言(例如C / C ++或Java)一样没有块。因此,Python中的作用域单位是一个函数。

Python does not have blocks, as do some other languages (such as C/C++ or Java). Therefore, scoping unit in Python is a function.


回答 2

一个非常有用的案例是使用时enumerate,您希望最终总数:

for count, x in enumerate(someiterator, start=1):
    dosomething(count, x)
print "I did something {0} times".format(count)

这有必要吗?不会。但是,这确实很方便。

要注意的另一件事:在Python 2中,列表推导中的变量也被泄漏:

>>> [x**2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> x
9

但是,这不适用于Python 3。

A really useful case for this is when using enumerate and you want the total count in the end:

for count, x in enumerate(someiterator, start=1):
    dosomething(count, x)
print "I did something {0} times".format(count)

Is this necessary? No. But, it sure is convenient.

Another thing to be aware of: in Python 2, variables in list comprehensions are leaked as well:

>>> [x**2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> x
9

But, the same does not apply to Python 3.


回答 3

如果您在循环中有一个break语句(并且想在以后使用迭代值,也许可以取回代码,为某些内容编制索引或提供状态),它可以节省一行代码和一次赋值,因此很方便。

If you have a break statement in the loop (and want to use the iteration value later, perhaps to pick back up, index something, or give status), it saves you one line of code and one assignment, so there’s a convenience.


回答 4

Python的主要影响力之一是ABC,这是一种在荷兰开发的语言,用于向初学者教授编程概念。Python的创建者Guido van Rossum在1980年代在ABC工作了几年。我对ABC几乎一无所知,但是由于它是面向初学者的,所以我认为它必须具有有限的作用域,就像早期的BASIC一样。

One of the primary influences for Python is ABC, a language developed in the Netherlands for teaching programming concepts to beginners. Python’s creator, Guido van Rossum, worked on ABC for several years in the 1980s. I know almost nothing about ABC, but as it is intended for beginners, I suppose it must have a limited number of scopes, much like early BASICs.


回答 5

对于初学者来说,如果变量是循环的局部变量,那么这些循环对于大多数现实世界的编程将毫无用处。

在当前情况下:

# Sum the values 0..9
total = 0
for foo in xrange(10):
    total = total + foo
print total

Yield45。现在,考虑分配在Python中的工作方式。如果循环变量严格是局部变量:

# Sum the values 0..9?
total = 0
for foo in xrange(10):
    # Create a new integer object with value "total + foo" and bind it to a new
    # loop-local variable named "total".
    total = total + foo
print total

产生0,因为total赋值后的循环内部与循环total外部的变量不同。这不是最佳或预期的行为。

For starters, if variables were local to loops, those loops would be useless for most real-world programming.

In the current situation:

# Sum the values 0..9
total = 0
for foo in xrange(10):
    total = total + foo
print total

yields 45. Now, consider how assignment works in Python. If loop variables were strictly local:

# Sum the values 0..9?
total = 0
for foo in xrange(10):
    # Create a new integer object with value "total + foo" and bind it to a new
    # loop-local variable named "total".
    total = total + foo
print total

yields 0, because total inside the loop after the assignment is not the same variable as total outside the loop. This would not be optimal or expected behavior.


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