有没有办法可视化一组 python 函数中的调用关系?

Is there a way to visualize the call relationships in a set of python functions?

假设您有一个包含许多 python 模块的文件夹,并且每个模块都包含函数。我想用顶点 = 函数名称可视化一个图。我想按如下方式定义边:如果函数 F1 调用 F2,则 F1 的顶点通过有向边连接到 F2。

单个模块的最小示例:

# --- module.py ---

def F1():
    pass

def F2():
    F1()

def F3():
    F1()

def F4():
    F2()

所需的输出将是一个图,其顶点为:V = {F1, F2, F3, F4},边为 E = {F2->F1, F3->F1, F4->F2}

有没有方便的库可以做到这一点?否则我想我可以将模块转换为字符串,识别函数并使用一些正则表达式查找内部调用。

谢谢

不确定它是否是一个 100% 可用的模型,但它有望成为一个起点。这背后的想法是使用一个装饰器来更新字典 graph,其值基于 inspect.currentframeinspect.getouterframesThis answer(说明如何获取调用者的姓名)已稍作修改以获取结果。

入口点称为 '<module>',因此如果您只关心相互调用的函数,您可以从图表中丢弃它。

import inspect
from collections import defaultdict

graph = defaultdict(set)

def called(fun):
    def inner(*args, **kwargs):
        cur_frame = inspect.currentframe()
        cal_frame = inspect.getouterframes(cur_frame)
        graph[cal_frame[1].function].add(fun.__name__)
        return fun(*args, **kwargs)
    return inner


@called
def f1():
    pass

@called
def f2():
    f1()
    f3()

@called
def f3():
    f1()

@called
def f4():
    f2()

v = {f1, f2, f3, f4}
f2()

print(graph)

输出

{'<module>': {'f2'}, 'f2': {'f1', 'f3'}, 'f3': {'f1'}}