python协程本质是生成器的扩展,但用途不同:生成器用于惰性产出数据,协程用于异步控制流;语法上,async/await是生成器语义的升级,原生协程对象不可用next()驱动,且只能await一次。

Python 协程本质上是生成器的扩展,但二者在设计目的、语法支持和运行机制上有明确区分:生成器用于惰性产生数据,协程用于暂停/恢复执行以实现异步逻辑。
生成器是协程的语法基础
Python 3.4 之前,协程完全基于生成器实现(即 基于生成器的协程)。通过 yield 和 send(),函数既能产出值,也能接收外部传入的值,从而具备“暂停-恢复”能力。这种能力被 asyncio 早期版本用作协程底层机制。
-
def gen(): yield 1是生成器函数,调用返回生成器对象; -
def coro(): yield from asyncio.sleep(1)在 Python 3.4–3.5 中属于生成器式协程,需用@asyncio.coroutine装饰器标记; - 两者都依赖生成器对象的
__next__()和send()方法驱动执行。
async/await 是生成器语义的语法糖升级
Python 3.5 引入 async/await 后,原生协程(coroutine object)不再继承生成器类型,但行为逻辑仍与生成器高度一致:可挂起、可等待、有状态机控制流。
通过使用BizPower CRM解决方案,您的员工、生产过程及信息能够与客户保持着平稳、无间断的联络,并且能够通过以客户为焦点、创新的产品和服务;以客户为中心,更高层次的生产过程;持久有益的客户关系这三个方面创造有价值客户的领导关系。选择Bizpower CRM的原因1、灵活的数据权限和功能权限BizPower CRM 系统通过引入了灵活的数据权限和功能权限,模仿现实中协同工作的实际情况。 实现企
-
async def f(): await asyncio.sleep(1)返回的是coroutine对象,不是generator; - 它不能用
next()或send()驱动,必须由事件循环用send()内部机制调度(底层仍复用生成器状态机); -
await只能接 awaitable 对象(包括协程、带__await__的对象、生成器经types.coroutine转换后也可成为 awaitable)。
关键区别:用途、类型与错误边界
生成器关注“产出”,协程关注“控制流协作”。混淆二者容易导致运行时错误。
立即学习“Python免费学习笔记(深入)”;
- 生成器抛出
StopIteration表示结束;协程抛出StopIteration(或返回值)表示完成,但该异常会被事件循环捕获并转为返回值; - 直接调用
next(gen)是合法的,但next(coro)会报TypeError: 'coroutine' object is not an iterator; - 生成器可迭代多次(重用需重建),协程对象只能被调度一次,重复
await会触发RuntimeError: cannot reuse already awaited coroutine。
实际开发中如何选择
除非需要手动控制迭代逻辑(如流式解析、内存敏感的数据管道),否则应优先使用 async/await 编写协程;生成器更适合同步场景下的惰性计算。
- 要异步读文件?用
async def read_async()+await aiofiles.open(); - 要逐行处理超大 CSV?用
def csv_rows(): yield row(同步生成器); - 需把旧生成器变成 awaitable?可用
@types.coroutine装饰,但仅限兼容场景,不推荐新代码使用。









