Python 中 'for' 循环的作用域
我并不是在问Python的作用域规则;我大致上明白Python中循环的作用域是怎么运作的。我的问题是,为什么会做出这样的设计决定。例如(没有双关的意思):
for foo in xrange(10):
bar = 2
print(foo, bar)
上面的代码会打印出(9,2)。
这让我觉得有点奇怪:'foo'实际上只是控制循环,而'bar'是在循环内部定义的。我可以理解为什么'bar'需要在循环外部也能被访问(否则,for循环的功能会非常有限)。但我不明白的是,为什么控制变量在循环结束后仍然需要保持在作用域内。在我的经验中,这样做只会让全局命名空间变得混乱,并且让我们更难找到在其他语言中解释器会捕捉到的错误。
8 个回答
一个非常有用的例子是使用 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 中,作用域的单位就是一个函数。
最可能的原因是,这样做让语法保持简单,没有成为大家使用时的障碍,而且很多人都很高兴在循环中给变量赋值时,不用去搞清楚这个变量属于哪个范围。变量并不是在某个范围内声明的,而是通过赋值语句的位置来暗示的。global
这个关键词就是为了这个目的而存在的(用来表示赋值是在全局范围内进行的)。
更新
这里有个不错的讨论,关于这个话题:http://mail.python.org/pipermail/python-ideas/2008-October/002109.html
之前有提议让for循环中的变量只在循环内部有效,但这个想法遇到了一个问题:有些现有的代码依赖于循环变量在循环结束后还能保持它的值,而这似乎被认为是一个很好的特性。
总之,你可能可以把这个归咎于Python社区 :P