繁体   English   中英

在 Python 调试器中等待异步 function

[英]Await an async function in Python debugger

在 Python 调试器中是否可以awaitasync function 的任意调用?

假设我在一些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)来解决这个问题,然后检查结果,但是当调试器处于活动状态时,我无法尝试实时调用我的函数。

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

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

这是我在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)更乏味,但它完成了工作。 希望将来会出现更优雅的解决方案。

我想补充@MD的答案。

将 nest_asyncio 应用到循环后,还可以添加以下 function:

def return_awaited_value(coroutine: asyncio.coroutine) -> Any:
  
    loop = asyncio.get_event_loop()
    result = loop.run_until_complete(coroutine)
    return result

如果您使用 VSCode 作为 IDE,那么这可以从 VSCode 的调试控制台运行为

result = return_awaited_value(bar(1))

并且 VSCode 会将其作为 object 返回,我发现它在调试时很有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM