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

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

上面将输出(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.


当前回答

最可能的答案是,它只是保持语法简单,并没有成为采用的绊脚石,而且许多人都很高兴在循环构造中为名称赋值时不必消除名称所属的作用域的歧义。变量不是在作用域中声明的,而是由赋值语句的位置暗示的。global关键字的存在就是因为这个原因(表示赋值是在全局范围内完成的)。

更新

这里有一个关于这个主题的很好的讨论:http://mail.python.org/pipermail/python-ideas/2008-October/002109.html

以前关于for循环的建议 循环的局部变量具有 偶然发现存在的问题 依赖于循环变量的代码 控件退出后保持其值 循环,似乎这是 被认为是可取的特征。

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

其他回答

一个非常有用的例子是当使用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。

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

这是Python中的一种设计选择,它通常使某些任务比使用典型块作用域行为的其他语言更容易。

但通常情况下,您仍然会错过典型的块作用域,因为,例如,您可能有需要尽快释放的大型临时数组。这可以通过临时的函数/类技巧来实现,但仍然有一个更整洁的解决方案,即直接操纵解释器状态。

from scoping import scoping
a = 2 

with scoping():
    assert(2 == a)
    a = 3
    b = 4
    scoping.keep('b')
    assert(3 == a) 

assert(2 == a) 
assert(4 == b)

https://github.com/l74d/scoping

如果您在循环中有一个break语句(并且希望稍后使用迭代值,可能用于恢复、索引某些东西或给出状态),那么它将为您节省一行代码和一次赋值,因此非常方便。

最可能的答案是,它只是保持语法简单,并没有成为采用的绊脚石,而且许多人都很高兴在循环构造中为名称赋值时不必消除名称所属的作用域的歧义。变量不是在作用域中声明的,而是由赋值语句的位置暗示的。global关键字的存在就是因为这个原因(表示赋值是在全局范围内完成的)。

更新

这里有一个关于这个主题的很好的讨论:http://mail.python.org/pipermail/python-ideas/2008-October/002109.html

以前关于for循环的建议 循环的局部变量具有 偶然发现存在的问题 依赖于循环变量的代码 控件退出后保持其值 循环,似乎这是 被认为是可取的特征。

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