首页 > 解决方案 > 如何打印已经返回的函数调用的堆栈跟踪?

问题描述

例如:

with magically_trace_stack() as trace:
    func(1, 2)
print(trace.format_tb())

func可以调用几十个其他函数,我想知道哪些。

(ps:不要给我推荐调试器)

扩展示例

def b():
    print('b')

def a():
    print('a')
    b()

def func():
    print('func')
    a()

with magically_trace_stack() as trace:
    func()
trace.print_stack()

打印堆栈应如下所示:

called func
called a
called b
exit b
exit a
exit func

功能ab被隐藏,我只能访问func.

标签: python

解决方案


sys.settrace您可以创建一个上下文管理器类,该类使用将跟踪事件和帧附加到列表的方法来启用解释器的跟踪功能:

import sys

class magically_trace_stack:
    def __init__(self):
        self.events = []

    def __enter__(self):
        sys.settrace(self.trace)
        return self

    def __exit__(self, *args):
        sys.settrace(None)

    def trace(self, frame, event, arg):
        # we don't want to record the call to the exit of the context manager
        if frame.f_code is not self.__exit__.__func__.__code__:
            self.events.append((frame, event, arg))
        return self.trace

    def print_stack(self):
        for frame, event, arg in self.events:
            if event == 'call':
                print(f'called {frame.f_code.co_name}')
            elif event == 'return':
                print(f'exit {frame.f_code.co_name} with {arg}')

以便:

def b():
    print('b')
    return 1

def a():
    print('a')
    b()
    return 2

def func():
    print('func')
    a()

with magically_trace_stack() as trace:
    func()
trace.print_stack()

输出:

func
a
b
called func
called a
called b
exit b with 1
exit a with 2
exit func with None

推荐阅读