asyncio中使用wait获取任务执行结果的正确方法是什么?
规范获取执行结果的方法
你不需要访问受保护的_result私有属性,所有asyncio.wait返回的Future/Task对象都提供了公开的.result()方法用于提取执行结果,done集合中的对象均为已完成状态,直接调用该方法即可,修正后的代码如下:
import asyncio async def foo(): return 1 # datetime.datetime.now() async def entry_point(): coros = [foo()]*3 done, pending = await asyncio.wait(coros, return_when=asyncio.FIRST_COMPLETED) for obj in done: print(obj.result()) # 官方推荐的规范写法 asyncio.run(entry_point())
如果你的需求仅为获取第一个完成的任务结果,不需要遍历集合,可以直接用next(iter(done)).result()快速取值,写法更简洁。
区分Task和Future的方法
Task是Future的子类,二者共享同一套公开接口,绝大多数场景下你不需要刻意区分二者类型,确实有区分需求时可以用isinstance方法判断:
- 判断对象是否为Future类型:
isinstance(obj, asyncio.Future) - 判断对象是否为Task类型:
isinstance(obj, asyncio.Task)
由于子类继承特性,asyncio.Task实例对上面两个判断都会返回True,需要区分时优先判断Task类型即可。
异常场景处理说明
如果任务执行过程中抛出未捕获的异常,直接调用.result()会重抛该异常,需要处理异常场景时可以先调用.exception()方法获取异常对象,无异常时该方法返回None,示例如下:
for obj in done: exc = obj.exception() if exc is not None: print(f"任务执行出错: {exc}") else: res = obj.result() print(f"任务执行结果: {res}")
内容的提问来源于stack exchange,提问作者Edgar Navasardyan
相关产品推荐
相关产品推荐

