如何正确为Coroutine(协程)函数添加类型提示?
协程类型提示的常见疑问与解答
问题背景
当定义异步函数时:
async def some_function(arg1: int, arg2: str) -> list: ...
该函数实际返回一个协程对象,这个协程被await后会返回list类型。如果要给这个函数变量做类型提示,初步写法是:
f: Callable[[int, str], Coroutine[???]] = some_function
但Coroutine是带3个泛型参数的类型,而Awaitable作为它的父类,仅带1个泛型参数(对应返回类型),于是产生以下核心疑问:
- 为
async def函数添加类型提示时,能否用Awaitable替代Coroutine? Coroutine泛型类型的正确参数是什么?适用场景有哪些?
解答
1. 可以用Awaitable替代Coroutine,且更推荐日常使用
async def定义的函数返回的对象同时实现了Coroutine和Awaitable接口,Awaitable是更抽象的上层类型——它只关注"可被await、最终返回指定类型"这一核心行为,不需要关心协程内部的底层交互细节。
你写出的Callable[[int, str], Awaitable[list]]是完全合法的写法,mypy、pyright等主流类型检查器都能正确识别这个异步函数的类型。在绝大多数业务代码场景中,使用Awaitable已经足够清晰,也更简洁。
2. Coroutine的泛型参数与适用场景
Coroutine的三个泛型参数定义为Coroutine[YieldType, SendType, ReturnType],各自含义如下:
- YieldType:协程通过
yield产出的值的类型(仅异步生成器会用到,普通async def函数填None) - SendType:可通过
coroutine.send()方法发送给协程的值的类型(普通async def函数填None) - ReturnType:协程被
await后最终返回的值的类型
因此,对于普通的async def函数,正确的Coroutine类型写法是:
f: Callable[[int, str], Coroutine[None, None, list]] = some_function
适用场景:
- 需要精确描述协程底层交互逻辑时(比如手动调用协程的
send()/throw()方法,或者处理异步生成器) - 某些对类型精度要求极高的场景,需要明确约束协程的输入输出细节,而非仅依赖抽象的
Awaitable
内容的提问来源于stack exchange,提问作者winwin
相关产品推荐
相关产品推荐

