我问的不是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.


当前回答

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

在当前情况下:

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

收益率45。现在,考虑在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不是同一个变量。这不是最优的或预期的行为。

其他回答

这是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

我可能是错的,但如果我确定不需要在循环之外访问foo,我会这样写

for _foo in xrange(10):
    bar = 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。

对Python的主要影响之一是ABC,一种荷兰开发的用于向初学者教授编程概念的语言。Python的创建者Guido van Rossum在20世纪80年代曾在ABC工作过几年。我对ABC几乎一无所知,但由于它是为初学者设计的,所以我想它的作用域一定是有限的,就像早期的BASICs一样。

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