等待Python调试器中的异步函数

Iva*_*ali 8 python debugging asynchronous ipdb python-asyncio

在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())
Run Code Online (Sandbox Code Playgroud)

现在,我想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
Run Code Online (Sandbox Code Playgroud)

当然,我可以通过在自己的x = await bar(1)之上ipdb.set_trace(),然后检查结果来解决此问题,但是当调试器处于活动状态时,我不能尝试实时调用我的函数。

M.D*_*.D. 6

这是我在/sf/answers/4749308021/上发布的内容的修改版本,因为它也解决了这个问题。

我找到了使用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())
Run Code Online (Sandbox Code Playgroud)

然后可以这样做:

      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
Run Code Online (Sandbox Code Playgroud)

诚然,这有点乏味,await bar(1)但它可以完成工作。希望将来能出现更优雅的解决方案。


Iva*_*ali 4

自Python 3.8以来,似乎开始更多地支持此功能。特别是看看这个问题bpo-37028

如果您仍在使用 Python 3.7,也许aiomonitor可以在一定程度上支持此功能。