从Python3.x到Python2.7的“yield from”语义的后台端口
yieldfrom的Python项目详细描述
从python 3.x到python 2.7的yield from
语义的后台端口
如果要在python 3.x中嵌套生成器,可以使用yield from
关键词。这允许您自动迭代子生成器和
透明地从顶级调用方传递异常和返回值
到最低的发电机。
def subgen(): yield 2 yield 3 def gen(): yield 1 yield from subgen() # Python 3.x only yield 4 def main(): for i in gen(): print i, >>> main() ... 1 2 3 4
此功能在Python2.x中不可用,我们使用
yieldfrom
装饰器和助手From
类:
from yieldfrom import yieldfrom, From def subgen(): yield 2 yield 3 @yieldfrom def gen(): yield 1 yield From(subgen()) yield 4 def main(): for i in gen(): print i, >>> main() ... 1 2 3 4
高级用法允许使用
StopIteration
。使用Return
可以方便地做到这一点:
from yieldfrom import yieldfrom, From, Return def subgen(): yield 2 yield 3 Return(100) # Raises `StopIteration(100)` @yieldfrom def gen(): yield 1 ret = (yield From(subgen())) yield 4 yield ret def main(): for i in gen(): print i, >>> main() ... 1 2 3 4 100
子生成器可以嵌套在多个级别上,每个级别都需要额外的
装饰方式yieldfrom
:
def subsubgen(): yield 2 @yieldfrom def subgen(): yield From(subsubgen()) yield 3 @yieldfrom def gen(): yield 1 yield From(subgen()) yield 4 def main(): for i in gen(): print i, >>> main() ... 1 2 3 4
抛出到顶级生成器中的异常可以在 子生成器:
def subsubgen(): try: yield 2 except ValueError: yield 200 @yieldfrom def subgen(): yield From(subsubgen()) yield 3 @yieldfrom def gen(): yield 1 yield From(subgen()) yield 4 def main(): try: g = gen() while True: i = g.next() if i == 2: i = g.throw(ValueError()) print i, except StopIteration: pass >>> main() ... 1 200 3 4
注意,如果对简单的iterable(list
)使用yield From()
,
tuple
等),则迭代器的各个成员将在
每次迭代(在这种情况下,您可能需要通常的yield
)。
@yieldfrom def gen(): yield From([1, 2, 3]) yield [1, 2, 3] def main(): for i in gen(): print i >>> main() ... 1 ... 2 ... 3 ... [1, 2, 3]
将不可iterable对象传递给From
将导致空
什么都不做的发电机。
@yieldfrom def gen(): yield From(None) yield 1 def main(): for i in gen(): print i >>> main() ... 1
此模块是对以下python配方的改编:
http://code.activestate.com/recipes/576727
修改包括异常处理、命名、文档中的错误修复,
处理空发电机等