Asyncio函数内为协程附加标识符抛出异常问题排查
错误原因
你在异常版本中传入asyncio.gather的不是可等待对象,而是(协程对象, symbol)的二元元组。asyncio.gather仅支持接收协程、Future或其他符合可等待协议的对象作为参数,传入元组自然触发类型错误;同时元组内的client.get返回的协程从未被执行或等待,因此也会抛出协程未等待的运行时警告。
修复方案
如果不想单独定义异步封装函数,可以选择以下两种常用实现方式:
方案1:利用返回结果顺序匹配
asyncio.gather返回结果的顺序和传入任务的顺序严格一致,你可以单独保存符号列表,请求完成后直接和结果按顺序拼接即可:
async def get_async_fixed(symbol_list: list)->list: async with httpx.AsyncClient(http2=True) as client: # 按符号顺序生成请求协程 tasks = [client.get(__search_url, params={'query': symbol}) for symbol in symbol_list] resps = await asyncio.gather(*tasks) # 按顺序拼接符号和返回结果 reqs = list(zip(resps, symbol_list)) for req in reqs: pprint(req)
方案2:内联临时异步函数绑定符号
如果需要直接在任务层面绑定符号,不需要额外定义全局异步函数,可以在循环内生成临时异步函数完成绑定:
async def get_async_fixed(symbol_list: list)->list: async with httpx.AsyncClient(http2=True) as client: tasks = [] for symbol in symbol_list: # 临时异步函数直接返回带符号的结果 async def _wrap(s): return await client.get(__search_url, params={'query': s}), s tasks.append(_wrap(symbol)) reqs = await asyncio.gather(*tasks) for req in reqs: pprint(req)
内容的提问来源于stack exchange,提问作者BeyondStupidQuestions
相关产品推荐
相关产品推荐

