Python 生成器中的 raise StopIteration 和 return 语句有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14183803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between raise StopIteration and a return statement in generators?
提问by slallum
I'm curious about the difference between using raise StopIterationand a returnstatement in generators.
我很好奇生成器中usingraise StopIteration和return语句之间的区别。
For example, is there any difference between these two functions?
例如,这两个功能有什么区别吗?
def my_generator0(n):
for i in range(n):
yield i
if i >= 5:
return
def my_generator1(n):
for i in range(n):
yield i
if i >= 5:
raise StopIteration
I'm guessing the more "pythonic" way to do it is the second way (please correct me if I'm wrong), but as far as I can see both ways raise a StopIterationexception.
我猜更“pythonic”的方式是第二种方式(如果我错了,请纠正我),但据我所知,两种方式都会引发StopIteration异常。
采纳答案by Jon Clements
There's no need to explicitly raise StopIterationas that's what a bare returnstatement does for a generator function - so yes they're the same. But no, just using returnis more Pythonic.
没有必要明确提出,StopIteration因为这是一个裸return语句对生成器函数所做的 - 所以是的,它们是相同的。但是不,只是使用return更Pythonic。
From: http://docs.python.org/2/reference/simple_stmts.html#the-return-statement(valid to Python 3.2)
来自:http: //docs.python.org/2/reference/simple_stmts.html#the-return-statement(对 Python 3.2 有效)
In a generator function, the return statement is not allowed to include an expression_list. In that context, a bare return indicates that the generator is done and will cause StopIteration to be raised.
在生成器函数中,不允许 return 语句包含 expression_list。在这种情况下,裸返回表示生成器已完成并将导致引发 StopIteration。
Or as @Bakuriu points out - the semantics of generators have changed slightly for Python 3.3, so the following is more appropriate:
或者正如@Bakuriu 指出的那样 - Python 3.3 的生成器语义略有变化,因此以下更合适:
In a generator function, the return statement indicates that the generator is done and will cause StopIteration to be raised. The returned value (if any) is used as an argument to construct StopIteration and becomes the StopIteration.value attribute.
在生成器函数中,return 语句表示生成器已完成并将引发 StopIteration。返回值(如果有)用作构造 StopIteration 的参数并成为 StopIteration.value 属性。
回答by Jon Clements
That's true, they are equivalent except that one is readable whereas the other is obscure. This dates back to the very first version of generators (PEP 255, under "Specification: Return"), and the subsequent enhancements of (such as coroutines) do not change this. 3.3's yield from(PEP 380) extends that to return <expr>as syntactic sugar for raise StopIteration(<expr>), but that doesn't change the meaning of return;.
没错,它们是等价的,只是一个可读而另一个模糊。这可以追溯到生成器的第一个版本(PEP 255,在“规范:返回”下),随后的增强(例如协程)不会改变这一点。3.3's yield from(PEP 380) 将其扩展return <expr>为 的语法糖raise StopIteration(<expr>),但这并没有改变return;.
回答by Blake Walsh
As of late 2014 returnis correct and raise StopIterationfor ending a generator is on a depreciation schedule. See PEP 479for full details.
截至 2014 年末return是正确的,并且raise StopIteration发电机处于折旧计划中。有关完整详细信息,请参阅PEP 479。
Abstract
This PEP proposes a change to generators: when
StopIterationis raised inside a generator, it is replaced withRuntimeError. (More precisely, this happens when the exception is about to bubble out of the generator's stack frame.) Because the change is backwards incompatible, the feature is initially introduced using a__future__statement.Acceptance
This PEP was accepted by the BDFL on November 22…
Rationale
The interaction of generators and StopIteration is currently somewhat surprising, and can conceal obscure bugs. An unexpected exception should not result in subtly altered behaviour, but should cause a noisy and easily-debugged traceback. Currently, StopIteration raised accidentally inside a generator function will be interpreted as the end of the iteration by the loop construct driving the generator.
…
抽象的
此 PEP 建议对生成器进行更改:当
StopIteration在生成器内升起时,它会替换为RuntimeError。(更准确地说,当异常即将从生成器的堆栈帧中冒出时,就会发生这种情况。)由于更改是向后不兼容的,因此该功能最初是使用__future__语句引入的。验收
该 PEP 于 11 月 22 日被 BDFL 接受......
基本原理
生成器和 StopIteration 的交互目前有些令人惊讶,并且可以隐藏不为人知的错误。意外异常不应导致行为发生微妙的改变,而应导致嘈杂且易于调试的回溯。目前,在生成器函数中意外引发的 StopIteration 将被驱动生成器的循环构造解释为迭代的结束。
…

