python-asyncio:走上协程链

时间:2017-09-16 22:00:35

标签: python python-asyncio coroutine

我想检查正在运行的协程中的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()

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

bar
foo
run

我查看了Task.get_stack,但是文档指出这个方法会为所有挂起的协同程序返回一个框架,这似乎没用。

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

1 个答案:

答案 0 :(得分:0)

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

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()