yield from

Posted 青山应回首

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了yield from相关的知识,希望对你有一定的参考价值。

 

参考:http://aju.space/2017/07/31/Drive-into-python-asyncio-programming-part-1.html

 

 

yield from  是Python 3.3 新引入的语法(PEP 380)。

它主要解决的就是在生成器里玩生成器不方便的问题。它有两大主要功能;

 

第一个功能是:让嵌套生成器不必通过循环迭代yield,而是直接yield from

以下两种在生成器里玩子生成器的方式是等价的:

# 方式一:使用 yield
def gen_two():
    subgen = (i**2 for i in range(2,5))
    for item in subgen:
        yield item

b = gen_two()
print(type(b),b)
for j in b:
    print(j)


# 方式二:使用 yield from
def gen_one():
    subgen = (i**2 for i in range(2,5))
    yield from subgen

a = gen_one()
print(type(a),a)
for i in a:
    print(i)

  

第二个功能:在子生成器和原生成器的调用者之间打开双向通道,两者可以直接通信。

def gen():
    yield from subgen()
    print("end gen...")

def subgen():
    try:
        while True:
            x = yield
            yield x+1
    except Exception as e:
        print("StopIteration in subgen...")

if __name__ == ‘__main__‘:
    g = gen()
    g.send(None)                # 驱动生成器g开始执行到第一个 yield
    retval = g.send(1)          # 看似向生成器 gen() 发送数据
    print(retval)               # 返回2
    g.throw(StopIteration)      # 看似向gen()抛入异常


### 结果 ###
2
StopIteration in subgen...
end gen...
Traceback (most recent call last):
  File "D:/soft/work/Python_17/day25/async_IO/xxx.py", line 75, in <module>
    g.throw(StopIteration)      # 看似向gen()抛入异常
StopIteration

  

关键字yield from在gen()内部为subgen()和main()开辟了通信通道。

main()里可以直接将数据1发送给subgen(),
subgen()也可以将计算后的数据2返回到main()里;

main()里也可以直接向subgen()抛入异常以终止subgen()。



顺带一提:
yield from 除了可以 yield from <generator> 还可以 yield from <iterable>。

  

 

以上是关于yield from的主要内容,如果未能解决你的问题,请参考以下文章

知识点:从迭代器一直到yield from

24 点游戏算法题的 Python 函数式实现: 学用itertools,yield,yield from 巧刷题

yield 与 yield from

Python `yield from`,还是返回一个生成器?

yield与yield from

python yield,yield from,深浅拷贝