在 Python 中,yield from 是用于生成器委托的语法,但在普通生成器和异步生成器里的使用规则并不一样。普通生成器可以直接用 yield from 调用子生成器,而异步生成器由于运行在事件循环上,不能用 yield from,需要用 async for 与 await 来驱动。

普通生成器中 yield from 的规则
普通生成器函数使用 def 定义,内部可用 yield from 把产出工作交给另一个生成器。它会自动处理子生成器的 next、send 和 throw,直到子生成器耗尽。
def sub_gen():
yield 1
yield 2
def main_gen():
# 普通生成器使用 yield from 委托
yield from sub_gen()
yield 3
for v in main_gen():
print(v)
# 输出 1 2 3
主要特点
- 可以用 yield from 直接嵌套生成器
- 支持 send 向子生成器传值
- 子生成器抛出的异常会向上传递
异步生成器中为什么不能用 yield from
异步生成器用 async def 定义,内部用 await 和 yield。由于异步生成器基于协程,每次迭代都需要事件循环调度,而 yield from 是同步语法,无法 await,因此在异步生成器里写 yield from 会报语法错误。
import asyncio
async def async_sub():
yield 1
yield 2
async def async_main():
# 下面这行会语法错误,不能用 yield from
# yield from async_sub()
async for v in async_sub():
yield v
async def run():
async for val in async_main():
print(val)
asyncio.run(run())
正确委托方式
异步生成器之间委托要用 async for 遍历子异步生成器,并在循环里 yield 出去,必要时用 await 处理异步逻辑。
async def async_main_ok():
ag = async_sub()
async for item in ag:
# 可在此处 await 其他协程
yield item
二者规则对比
| 对比项 | 普通生成器 | 异步生成器 |
|---|---|---|
| 定义方式 | def | async def |
| 委托语法 | yield from | async for + yield |
| 是否可 await | 否 | 是 |
| 驱动方式 | for 或 next | async for 或 anext |
异常传递区别
普通生成器中,调用方用 throw 抛入的异常会进入 yield from 所指的子生成器。异步生成器没有 yield from,异常通常通过 async for 循环或 ag.athrow 控制,需要自行在 async for 中捕获处理。
记住:普通生成器用 yield from 做同步委托,异步生成器用 async for 做异步迭代,二者不可混用。
小结
写异步代码时,如果看到异步生成器里写了 yield from,基本就是错误用法。应当改用 async for 遍历子异步生成器并 yield 元素,这样才能和事件循环配合正常工作。
yield_from异步生成器普通生成器修改时间:2026-07-28 03:33:09