【问题标题】:Is there a way to visualize the call relationships in a set of python functions?有没有办法在一组 python 函数中可视化调用关系?
【发布时间】:2021-02-05 13:26:13
【问题描述】:

假设您有一个包含许多 python 模块的文件夹,每个模块都包含函数。我想用 vertices = 函数名来可视化一个图。我想如下定义边:如果函数 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}

是否有方便的库来执行此操作?否则我想我可以将模块转换为字符串,识别函数并使用一些正则表达式找到内部调用。

谢谢

【问题讨论】:

    标签: python graph project-structure


    【解决方案1】:

    不确定它是否是 100% 有效的模型,但希望它可以作为一个起点。这背后的想法是使用一个装饰器,它将使用基于inspect.currentframeinspect.getouterframes 的值更新字典graphThis 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'}}
    

    【讨论】:

    • 谢谢!这非常有用。 TBH 我很惊讶没有这样的库。
    • 好吧,你可以试试这个,如果它有效,如果没有任何其他有用的答案,你可以接受这个答案,我会编辑这个,因为我找到更好的方法,可能有 3rd 方库但是我想看看我能不能破解我自己的东西
    • 我想避免使用装饰器。
    • 您是否有理由避免使用它们?
    • 是的,我在某些函数中使用了其他装饰器,并且我不想在之后手动添加和删除它们。
    猜你喜欢
    • 1970-01-01
    • 2021-06-29
    • 2020-08-18
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 2016-08-01
    • 1970-01-01
    • 2021-07-06
    相关资源
    最近更新 更多