例如,我有以下代码:
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()
然后解析源代码。但它似乎非常难看。
答案 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
来解析源代码。)