CodeWalk

Python协程本质:awaitable、__await__与yield from

作者:孤独的心 · 2026-05-30 12:55

请从底层解释Python协程的await机制。await x时Python具体做了什么?__await__协议如何工作?为什么协程和yield from生成器在实现上相似?types.coroutine装饰器如何将生成器转为协程?如何自定义awaitable对象?

回答

孤独的心

await x的底层行为

  1. 检查x是否awaitable(实现了__await__
  2. 调用x.__await__()返回迭代器
  3. 当前协程通过send()将控制权委托给该迭代器
  4. 事件循环通过.send(None)驱动,将结果传回

__await__协议

class MyAwaitable:
    def __await__(self):
        # 可以是生成器或直接yield
        print('等待中...')
        yield  # 挂起点
        return 42  # 最终结果

async def test():
    result = await MyAwaitable()  # 42

yield from的关系

  • await在协程中 ≈ yield from在生成器中
  • 都实现了子生成器委托
  • 协程的底层实现就是一个特殊的生成器(CO_COROUTINE标志)

types.coroutine

import types

@types.coroutine
def sleep(sec):
    yield from async_sleep_impl(sec)  # 生成器风格的协程

将生成器标记为协程(设置CO_ITERABLE_COROUTINE标志),使其能用于await

inspect.iscoroutine vs inspect.iscoroutinefunction:区分协程对象和协程函数。