有没有办法可视化一组 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.currentframe
和 inspect.getouterframes
。 This 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'}}
假设您有一个包含许多 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.currentframe
和 inspect.getouterframes
。 This 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'}}