`from foo()`和`for f in foo()之间的区别:yield x`

时间:2014-09-17 12:30:19

标签: python python-3.x generator yield yield-from

在Python中,大多数收益率的例子都是用

来解释它
yield from foo()

类似于

for x in foo(): yield x

另一方面,它似乎并不完全相同,并且有一些魔法投入。我觉得使用一个我不理解的魔法的功能有点不安。我需要了解yield from的魔法,以避免陷入魔法做我不期望的事情的情况?我应该注意到魔法提供了哪些优势?

1 个答案:

答案 0 :(得分:13)

foo()返回常规可迭代时,两者是等价的。当foo()也是生成器时,“魔法”就会发挥作用。那时,yield from foo()for x in foo(): yield x案件存在重大差异。

使用generator.send() method,生成器也可以发送数据。当您使用for循环时,yield x表达式'接收'发送的数据; foo()生成器永远不会看到这个。但是当您使用yield from时,发送的数据将直接转到委托生成器当前暂停的任何yield表达式。换句话说,yield from传递已发送的数据,因此委托生成器可以接收它。

您还可以使用generator.throw()在生成器中引发异常;对于for循环的情况,异常从yield x行引发,而yield from则异常再次传递;异常是在foo()内引发的。

这意味着yield from 本质上在委托迭代的持续时间内替换当前生成器。

委托生成器也可以与父生成器通信,完成后,.value异常引发的StopIteration属性将作为yield from表达式的值返回。您可以在委派给return <expression>生成器中使用foo()来设置该例外的值,也可以明确使用raise StopIteration(<expression>)

yield from已通过PEP 380: Syntax for Delegating to a Subgenerator引入语言。