生成器是 Python 中处理迭代和惰性计算的利器。除了基础的 yield
,Python 还引入了更强大的 yield from
语法,它极大简化了生成器委托和协程的写法。本文将带你深入理解 yield from
及其在协程中的应用。
一、回顾基础生成器
基础生成器函数使用 yield
产生值:
python
复制编辑
def gen(): yield 1 yield 2 yield 3
二、生成器委托问题
有时生成器需要调用另一个生成器,传统写法需要循环转发:
python
复制编辑
def gen_sub(): yield 1 yield 2 def gen_main(): for value in gen_sub(): yield value yield 3
这种写法冗长且不便维护。
三、yield from 的作用
yield from <iterable>
用于简化生成器委托,自动处理子生成器的迭代和异常传递。
python
复制编辑
def gen_main(): yield from gen_sub() yield 3
这样写更简洁,语义更明确。
四、yield from 的原理
它会自动完成:
-
迭代子生成器的所有值
-
将
send()
,throw()
等方法传递给子生成器 -
返回子生成器的返回值(Python 3.3+)
五、yield from 与协程
Python 3.5 之前,基于生成器的协程利用 yield from
实现协程间的调度:
python
复制编辑
@asyncio.coroutine def foo(): yield from asyncio.sleep(1)
yield from
使得协程之间可以等待和传递结果。
六、实战示例:合并多个生成器
python
复制编辑
def gen1(): yield from range(3) def gen2(): yield from 'abc' for x in gen1(): print(x) for x in gen2(): print(x)
七、总结
yield from
是 Python 生成器进阶的利器,极大简化了生成器嵌套和协程实现。掌握它能让你写出更简洁、高效的迭代和异步代码。
https://bigu.wang
https://www.bigu.wang
https://binm.wang
https://www.binm.wang
https://bint.wang
https://www.bint.wang
https://biop.wang
https://www.biop.wang
https://bits.wang
https://www.bits.wang