在Python中确定'for'循环

chi*_*der 161 python scope

我不是在问Python的范围规则; 我一般都了解 Python for循环中的作用域是如何工作的.我的问题是为什么设计决策是以这种方式做出的.例如(没有双关语):

for foo in xrange(10):
    bar = 2
print(foo, bar)
Run Code Online (Sandbox Code Playgroud)

以上将打印(9,2).

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

Jer*_*own 98

最有可能的答案是,它只是保持语法简单,并不是采用的绊脚石,许多人都乐于在循环结构中分配名称时不必消除名称所属的范围.变量不在范围内声明,它由赋值语句的位置隐含.global关键字仅因此而存在(表示分配是在全局范围内完成的).

更新

以下是关于该主题的一个很好的讨论:http: //mail.python.org/pipermail/python-ideas/2008-October/002109.html

以前提出的循环变量局部循环的建议偶然发现现有代码的问题依赖于循环变量在退出循环后保持其值,并且似乎这被认为是一个理想的特征.

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

  • 循环不是Python中的块.这种行为改变要求从根本上改变语法或提供特殊情况.归纳变量的整个概念也没有在当前语法中表达.语法提供了解释器将如何解释的合同.我的观点是,我无法预见如何在不使语法更复杂的情况下改变这种行为.这一切都没有实际意义,因为设计决策的副作用已成为一个特征. (4认同)
  • 如果归纳变量的范围仅限于循环体,语法会如何更复杂?这种变化将仅限于 Python 中的语义分析,而不是其语法。 (2认同)
  • 解决方案可以像 JavaScript 中的“let”关键字一样简单。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let 大多数语言都有这样的简单机制,因为在可能的情况下使用和优先考虑本地范围显然是一个很好的实践。 (2认同)

atz*_*tzz 58

Python没有块,其他语言(如C/C++或Java)也没有.因此,Python中的作用域单元是一个函数.

  • 不是真的,只是语法不会疯狂.(http://docs.python.org/reference/executionmodel.html#naming-and-binding)"块是一段Python程序文本,作为一个单元执行.以下是块:模块,函数身体和课程定义......" (28认同)
  • @thebackhand - 在带有块的语言中,确定`for`循环是一般原则的自然延伸.在Python中,它必须是一个特殊情况,除非它们具有令人信服的好处,否则应避免使用特殊情况. (6认同)
  • 我很困惑 - 是什么阻止Python以与函数作用域相同的方式来寻找循环? (2认同)
  • @thebackhand,没什么。它只是被认为是不必要的。 (2认同)

car*_*arl 38

一个非常有用的情况是在使用时enumerate,你想要最终的总数:

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

这有必要吗?不,但是,它确实很方便.

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

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

但是,同样不适用于Python 3.

  • **对于count,枚举项(a,start = 1):**#default index从零开始 (6认同)
  • 你可以在`else`子句中做到这一点,即.`else:print"我做了{0}次".format(count)` - 在本地范围之前(在Python中不存在)消失了 (3认同)
  • 只有第二个例子在Python 3中不起作用,对吗?第一个还在吗?注意为什么它从Python 3中删除了? (3认同)
  • 第一个例子,而不是一个好的用例,似乎更像是这个范围规则是危险的,不应该依赖的证据.如果`someiterator`为空怎么办? (3认同)

kin*_*all 5

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