Scoping in Python 'for' loops
我不是在问关于Python的作用域规则;我通常理解在Python for循环中作用域是如何工作的。我的问题是为什么设计决策是这样做的。例如(没有双关语):
1 2 3 | for foo in xrange(10): bar = 2 print(foo, bar) |
上面将打印(9,2)。
这让我觉得很奇怪:"foo"实际上只是控制循环,而"bar"是在循环中定义的。我可以理解为什么"bar"可能需要在循环外部进行访问(否则,对于循环而言,功能将非常有限)。我不明白的是,为什么在循环退出后控制变量必须保持在范围内。根据我的经验,它只会使全局名称空间变得混乱,并使跟踪其他语言的解释程序可能捕获的错误变得更加困难。
最有可能的答案是,它只是保持了语法的简单性,并没有成为采用的绊脚石,而且许多人很高兴在循环构造中为其分配名称时,不必消除名称所属范围的歧义。变量不是在作用域内声明的,而是由赋值语句的位置所隐含的。
更新
下面是关于这个主题的一个很好的讨论:http://mail.python.org/pipermail/python-ideas/2008-10月/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.
简而言之,您可以将其归咎于Python社区:p
Python没有块,像其他一些语言(如C/C++或Java)一样。因此,python中的作用域单元是一个函数。
一个非常有用的例子是,当使用
1 2 3 | for count, x in enumerate(someiterator, start=1): dosomething(count, x) print"I did something {0} times".format(count) |
这是必要的吗?不,但是,它确实很方便。
另一件需要注意的事情是:在python 2中,列表理解中的变量也会泄漏:
1 2 3 4 | >>> [x**2 for x in range(10)] [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> x 9 |
但是,这同样不适用于Python3。
如果循环中有一个break语句(并且希望稍后使用迭代值,可能是为了备份、索引某些内容或给出状态),那么它将为您节省一行代码和一个分配,因此非常方便。
对python的主要影响之一是abc,这是一种在荷兰为初学者教授编程概念而开发的语言。python的创建者guido van rossum在20世纪80年代在abc工作了几年。我对abc几乎一无所知,但由于它是为初学者设计的,我想它必须有有限的范围,就像早期的基础知识一样。
对于初学者来说,如果变量是循环的局部变量,那么这些循环对于大多数实际编程都是无用的。
在当前情况下:
1 2 3 4 5 | # Sum the values 0..9 total = 0 for foo in xrange(10): total = total + foo print total |
生成
1 2 3 4 5 6 7 | # 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 |
生成