是否可以在 Python 调试器中await
对async
函数的任意调用?
假设我在某个main.py
文件中有以下代码:
import asyncio
async def bar(x):
return x + 1
async def foo():
import ipdb; ipdb.set_trace()
asyncio.run(foo())
现在我想在调试器中使用一些参数来测试调用bar()
以测试结果。将发生以下情况:
$ python3 main.py
> /Users/user/test/main.py(8)foo()
7 import ipdb; ipdb.set_trace()
----> 8 return None
9
ipdb> bar(1)
<coroutine object bar at 0x10404ae60>
main.py:1: RuntimeWarning: coroutine 'bar' was never awaited
import asyncio
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
ipdb> await bar(1)
*** SyntaxError: 'await' outside function
当然,我可以通过在我的ipdb.set_trace()
上方放置x = await bar(1)
来解决这个问题,然后检查结果,但是我不能尝试在调试器处于活动状态时实时调用我的函数。
这是我在 https://stackoverflow.com/a/67847257/893857 发布的内容的修改版本,因为它也解决了这个问题。
我找到了使用nest_asyncio的解决方案。如果有以下异步示例脚本:
import asyncio
import nest_asyncio
async def bar(x):
return x + 1
async def foo():
import ipdb; ipdb.set_trace()
if __name__=="__main__":
loop = asyncio.get_event_loop()
nest_asyncio.apply(loop)
loop.run_until_complete(foo())
然后可以做:
8 async def foo():
----> 9 import ipdb; ipdb.set_trace()
10
ipdb> loop = asyncio.get_event_loop()
ipdb> loop.run_until_complete(bar(1))
2
诚然,它比await bar(1)
更乏味,但它可以完成工作。希望将来会出现一个更优雅的解决方案。
似乎从 Python 3.8 开始对此功能提供更多支持。特别是,看看这个问题 bpo-37028
如果你还在使用 Python 3.7,也许 aiomonitor 可以在一定程度上支持这个功能。