Python协程本质:awaitable、__await__与yield from
请从底层解释Python协程的await机制。await x时Python具体做了什么?__await__协议如何工作?为什么协程和yield from生成器在实现上相似?types.coroutine装饰器如何将生成器转为协程?如何自定义awaitable对象?
回答
孤独的心
await x的底层行为:
- 检查
x是否awaitable(实现了__await__) - 调用
x.__await__()返回迭代器 - 当前协程通过
send()将控制权委托给该迭代器 - 事件循环通过
.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:区分协程对象和协程函数。