`foo()的yield和foo()中的x的区别:yield x` [英] Difference between `yield from foo()` and `for x in foo(): yield x`
问题描述
在Python中,大多数产生收益的示例都说
In Python most examples of yield from explain it with saying that
yield from foo()
与
for x in foo(): yield x
另一方面,它似乎并不完全相同,并且抛出了一些魔术.对于使用执行我不了解的魔术的函数,我感到有些不安.关于yield from
的魔术,我必须了解些什么,以避免陷入魔术无法完成的事情?我应该知道魔术提供了哪些优势?
On the other hand it doesn't seem to be exactly the same and there's some magic thrown in. I feel a bit uneasy about using a function that does magic that I don't understand. What do I have to know about the magic of yield from
to avoid getting into a situation where the magic does something I don't expect? What advantages does the magic provide, that I should be aware of?
推荐答案
当foo()
返回常规可迭代对象时,两者是等效的.当foo()
也是 generator 时,魔术"开始起作用.那时,yield from foo()
和for x in foo(): yield x
情况大不相同.
When foo()
returns a regular iterable, the two are equivalent. The 'magic' comes into play when foo()
is a generator too. At that moment, the yield from foo()
and for x in foo(): yield x
cases differ materially.
A generator can be sent data too, using the generator.send()
method. When you use the for
loop, the yield x
expression 'receives' the sent data; the foo()
generator will never see this. But when you use yield from
the sent data goes straight to whatever yield
expression the delegated-to generator is currently paused at. In other words, yield from
passes on the sent data so the delegated-to generator can receive it instead.
You can also raise exceptions in a generator, with generator.throw()
; with the for
loop case, the exception is raised from the yield x
line, while with yield from
the exception is passed on again; the exception is raised inside foo()
instead.
在一起,这意味着yield from
本质上在委派迭代的持续时间内替换了当前生成器.
Together, this means that yield from
in essence replaces the current generator for the duration of the delegated iteration.
受委托生成器还可以与父生成器进行通信,完成后,将引发StopIteration
异常的.value
属性作为yield from
表达式的值返回.您可以使用委托给foo()
生成器中的return <expression>
来设置该异常的值,也可以显式使用raise StopIteration(<expression>)
.
The delegated-to generator also gets to communicate with the parent generator, when done the .value
attribute of the StopIteration
exception raised is returned as the value of the yield from
expression. You can set the value of that exception by using return <expression>
in the delegated-to foo()
generator, or you can use raise StopIteration(<expression>)
explicitly.
yield from
通过 PEP 380:语法用于委托给子生成器 .
这篇关于`foo()的yield和foo()中的x的区别:yield x`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!