如何获取任何函数的函数堆栈跟踪?

时间:2014-12-18 07:07:26

标签: python parsing python-3.x stack-trace

例如,我有以下代码:

def m1(num):
    pass


def m2(num):
    pass


def foo(num):
    m2(num)


def foo2(num):
    foo(num)
    m1(num)

def main():
    foo2(1)


if __name__ == "__main__":
    main()

有没有办法获取每个功能的通话清单?例如,对于此示例,我想获得以下dict:

main: foo2
foo2: foo, m1
foo: m2
m2: 
m1: 

我只知道完成任务的一种方法。它是使用globals()然后解析源代码。但它似乎非常难看。

1 个答案:

答案 0 :(得分:1)

  

我只知道完成任务的一种方法。它是使用globals()然后解析源代码。但它似乎非常难看。

我不确定你认为解析源代码会对你做什么。


如果你想构建一个动态调用图,你想要做的是装饰每个函数 - 用一个包装器替换它,在调用实际函数之前或之后做一些额外的东西。例如:

def wrapper(func):
    @functools.wraps
    def wrap(*args, **kwargs):
        # do stuff to update call graph
        return func(*args, **kwargs)
    return wrap

g = globals()
for name, value in g.items():
    if callable(value):
        g[name] = wrapper(value)

或者,可能更简单(也更灵活),您可能希望使用bdb调试器框架来逐步执行您的程序并只记录user_call个实例。


如果你想构建一个静态调用图,那么很明显它来自源代码,但当Python附带ast时,没有理由自己解析它模块为你做的。 (您可以使用inspect.getsource来解析源代码。)