python循环语句范围_关于范围:Python’for’循环中的范围

我不是在问关于Python的作用域规则;我通常理解在Python for循环中作用域是如何工作的。我的问题是为什么设计决策是这样做的。例如(没有双关语):

for foo in xrange(10):

bar = 2

print(foo, bar)

上面将打印(9,2)。

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

如果您不想让for循环凌乱您的全局命名空间,请将其包装在一个函数中。关闭太多了!

除非在全局命名空间中运行循环(不常见),否则它会使本地命名空间混乱。

如果这不存在,您将如何在稍后在循环中遗漏的点继续处理?只需在循环之前定义控制变量?

@内石是的…为什么不需要呢?

@史蒂文鲁:因为那样做会更有效,不会有什么好处?

好吧,人们只是更喜欢他们习惯做的事情。我想说的是,这类事情伤害了Python编码人员,他们习惯了这类事情,在切换到其他语言时,必须经历一个痛苦的过程。对我们其他人来说,我想这是一条很好的捷径。

@史蒂文鲁:所以我们不应该创造出好的语言,因为换成蹩脚的语言的痛苦更明显?:)

不,不必初始化这些变量会使python变得更好,大多数人都会同意。必须权衡选择

对于一种使用空白空间作为管理范围的"优雅"方式的语言来说,这让我非常害怕。这让我怀疑我的任何"作用域"变量是否真的在它们自己的作用域中。

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

更新

下面是关于这个主题的一个很好的讨论: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中的语义分析,而不是语法分析。

循环不是Python中的块。这种行为改变需要从根本上改变语法或者提供一个特殊的例子。归纳变量的整个概念在当前语法中也没有表达出来。语法为口译员如何解释提供了契约。我的观点是,如果不使语法变得更复杂,我就无法预见这种行为的变化是如何完成的。因为设计决策的副作用已经成为一个特征,所以这一切都是没有意义的。

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

我很困惑-是什么阻止了python以与函数的作用域相同的方式定义循环的作用域?

不是真的,只是语法不会变得疯狂。(docs.python.org/reference/…)"块是作为一个单元执行的一段python程序文本。以下是块:模块、函数体和类定义…"

@背后,什么都没有。只是觉得没必要。

@杰里米·布朗——真的。好注意。

@在带有块的语言中,作用于for循环的范围是一般原则的自然扩展。在Python中,它必须是一个特殊的情况,并且必须避免特殊的情况,除非它们具有令人信服的好处。

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

但是,这同样不适用于Python3。

您可以在else子句中这样做,即else: print"I did something {0} times".format(count)—在本地作用域(在python中不存在)消失之前。

只有第二个例子在python 3中不起作用,对吗?第一个还是吗?注意为什么从python 3中删除它?

对于count,enumerate(a,start=1)中的项:默认索引为零

第一个例子,而不是一个好的用例,更像是这个范围界定规则是危险的,不应该被依赖的证据。如果someiterator是空的呢?

@nas虽然在这种情况下可以使用else子句,但一般来说它不起作用,因为循环体会过早地break子句。

无聊的。在第一个示例中有一个逐一错误。

如果循环中有一个break语句(并且希望稍后使用迭代值,可能是为了备份、索引某些内容或给出状态),那么它将为您节省一行代码和一个分配,因此非常方便。

对python的主要影响之一是abc,这是一种在荷兰为初学者教授编程概念而开发的语言。python的创建者guido van rossum在20世纪80年代在abc工作了几年。我对abc几乎一无所知,但由于它是为初学者设计的,我想它必须有有限的范围,就像早期的基础知识一样。

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

在当前情况下:

# 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不是同一变量。这不是最佳或预期的行为。

没有回答问题。OP询问的是foo,而不是total(或者他们例子中的bar)。

@jamesbradbury-total和foo在操作场景中仍然有循环本地绑定,逻辑相同。

OP:"我可以理解为什么可能需要在循环外部访问‘bar’(否则,对于循环,功能将非常有限)。我不明白的是,为什么在循环退出后控制变量必须保持在范围内。

@你也许是对的,但我三年前回答了这个问题,现在可能不值得讨论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值