python - 确保 aiohttp/asyncio 中递归函数的未来
问题描述
我遇到了在事件循环中未正确调用递归函数的问题。我有以下内容:
async def get_response(session, url, attempt=0):
async with session.get(url) as response:
if response.status == 200:
return await response.json()
elif attempt < 3:
# This never gets called, a coroutine is returned
return get_response(session, url, attempt + 1)
else:
return None
async def main(loop):
output = []
urls = ["https://httpbin.org/json"]
async with aiohttp.ClientSession(loop=loop) as session:
tasks = []
for url in urls:
tasks.append(asyncio.ensure_future(get_response(session, url)))
for future in await asyncio.gather(*tasks):
output.append(future)
return output
if __name__ == '__main__':
loop = asyncio.get_event_loop()
output = loop.run_until_complete(main(loop))
问题出现在get_response
它attempt < 3
实际上不会再次运行该功能的地方。上面的代码可以正常工作,因为https://httpbin.org/json
将返回 200 代码。如果我错了,请纠正我(因为我可能是),但我在想,既然函数的迭代不在任务列表中,main
那么它实际上不会运行?我调试时得到的回报是一个实际的协程对象,而不是None
我想要的。
future
确保在必要时再次调用a 中的递归函数的正确方法是什么?
解决方案
与get_response
async 一样,您需要在调用它时等待它,即使是从它本身这样做。所以,你需要改变:
return get_response(session, url, attempt + 1)
到:
return await get_response(session, url, attempt + 1)
推荐阅读
- powershell - 有没有办法根据 LastWriteAccess 日期列出文件?
- sendbeacon - 如何在服务器端获取读取数据发送信标?
- python - Python,使用 sys.path.append() 与相对导入导入包的风险?
- java - 为什么 DP 解决方案不起作用,捕获雨水?
- java - 我将@Entity 数据注释添加到房间数据库的类 android 时出错
- c# - 使用大量项目填充组合框
- webhooks - 如何从海康威视相机获取事件到我的 Typescript 项目,相机内部 API 是否有任何文档?
- python-3.x - 如何使用 python 从 Tableau Desktop 自动“手动刷新”?
- google-oauth - 如何以编程方式将凭据传递到 googleapiclient?
- spring - JSR Bigdecimal 验证不适用于@Digits