问题描述
假设你有一个文件夹,里面有很多 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'}}