【问题标题】:python-asyncio: walk up the coroutine chainpython-asyncio:走上协程链
【发布时间】:2018-02-25 18:44:48
【问题描述】:

我想检查正在运行的协程中的await 调用链。我的目标是向我的用户展示一个图表,显示哪些协程在我支持的应用程序中相互调用。但是,一个简单的堆栈是行不通的,因为协程可能会同时运行。

这是我使用cr_wait 进行的快速测试以遍历堆栈。我看到了这种方法here,但它并没有产生我预期的结果。

from asyncio import get_event_loop
from asyncio import Task


def main():
    loop = get_event_loop()
    loop.run_until_complete(run())


async def run():
    await foo()


async def foo():
    await bar()


async def bar():
    print_coro_stack(Task.current_task()._coro)


def print_coro_stack(coro):
    if coro is None:
        return
    print(coro.__name__)
    if coro.cr_await:
        print_coro_stack(coro.cr_await)


if __name__ == '__main__':
    main()

执行时,此代码仅打印“运行”。我曾(也许是天真地)期望看到:

bar
foo
run

我查看了Task.get_stack,但文档指出,此方法将为所有挂起的协程返回一个帧,这似乎没什么用。

有没有办法获得完整的协程堆栈?

【问题讨论】:

    标签: python python-asyncio coroutine


    【解决方案1】:

    我不知道这是否满足您的问题,但您可以做的是遍历帧:

    from asyncio import get_event_loop
    from asyncio import Task
    import inspect
    
    def main():
    
        loop = get_event_loop()
        loop.run_until_complete(run())
    
    
    async def run():
        await foo()
    
    
    async def foo():
        await bar()
    
    async def bar():
        print_frame_stack(inspect.currentframe())
    
    
    def print_frame_stack(frame):
        if frame is None:
            return
        print(frame.f_code.co_name)
        if frame.f_back:
            print_frame_stack(frame.f_back)
    
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

      猜你喜欢
      • 2020-12-29
      • 1970-01-01
      • 2019-03-16
      • 1970-01-01
      • 1970-01-01
      • 2020-07-03
      • 2020-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多