[Python] 绘制Python代码的函数调用关系:graphviz+pycallgraph


文章目录

  • [Python] 绘制Python代码的函数调用关系:graphviz+pycallgraph
  • 问题描述
  • 解决方案
  • 安装graphviz函数库
  • 安装pycallgraph函数库
  • 关于安装函数库,我想多说的两点。
  • 安装graphviz-2.38软件
  • 核心代码


问题描述

不知道大家有没有遇到这样的问题:尤其是代码很长,或者整体逻辑不太好的时候,代码在脑袋里就是一团乱麻,从而给代码阅读和调试,以及移植等操作,增加巨大的困难。

这时候我就想,如果能把代码的结构可视化一下就好了。


解决方案

在这个问题下,绘制Python代码的函数调用关系就成了一个自然而然的解决方案。

先上结果图:

python中层间调用关系是通过方式实现的 python 函数调用关系图_anaconda


安装graphviz函数库

安装方法见:graphviz官方文档

安装命令是:

pip install graphviz

安装pycallgraph函数库

安装方式见官网:pycallgraph官方文档

安装命令是:

pip install pycallgraph

关于安装函数库,我想多说的两点。
  1. 多看官方文档,少看各种博客。
    作为跟程序打交道的,以后看官方文档的时候多了去了。现在不锻炼着,以后就干着急吧。
    而且现在的一些博客,大部分来说,写的太粗糙太粗糙。放出来的都是别人自己嚼烂的,对不对,全不全,都要打个问号。
    很多时候我看到百度搜索前几的博客,其内容水平真是让我大跌眼镜,满头问号。
    相反的,官方文档及其GitHub写的要更为精简和规范。
  2. 注意区分原生的Python环境和Anaconda下的环境。
    直接的结果就是,打开命令行直接pip install XXX,是不能在使用Anaconda下的Pycharm中使用的。
    具体的原因和做法,参见之前写的另一个博客:[python+pip] 使用pip将函数库安装到Python环境或Anaconda环境

安装graphviz-2.38软件

pycallgraph函数库在使用的时候,要使用dot的功能。而要dot功能的话,就要下载 graphviz-2.38。

否则会出现以下报错信息:

'The command "{}" is required to be in your path.'.format(cmd))
pycallgraph.exceptions.PyCallGraphException: The command "dot" is required to be in your path.

关于这个报错的详细解释,可以看一下stackoverflow上的两个回答:

下载的链接放到这:Graphviz。由于是境外下载,速度会比较慢。

我自己的下好的压缩包上传到CSDN了,免费的:graphviz-2.38安装程序(免费)

安装完之后还要将其路径增加到环境变量中,一般是C:\Program Files (x86)\Graphviz2.38\bin。然后就大功告成了!

怎么修改环境变量,见:设置Python环境变量-Windows10


核心代码

from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput
from pycallgraph import Config
from pycallgraph import GlobbingFilter

def main():
    graphviz = GraphvizOutput()
    graphviz.output_file = 'basic.png'

    with PyCallGraph(output=graphviz):
        k_fold_cross_validation(10, x, label)  # k=10,十折交叉验证

if __name__ == '__main__':
    main()

或者指定只绘制相应函数的操作:

def main():
	# 主函数代码。
        
if __name__ == "__main__":
    config = Config()
    # 关系图中include的函数名。
    # 如果是某一类的函数,例如类gobang,则可以直接写'gobang.*',表示以gobang.开头的所有函数。(利用正则表达式)。
    config.trace_filter = GlobbingFilter(include=[
        'main',
        'train',
    ])
    该段作用是关系图中exclude的函数。(正则表达式规则)
    config.trace_filter = GlobbingFilter(exclude=[
        'pycallgraph.*',
    ])
    
    graphviz = GraphvizOutput()
    graphviz.output_file = 'basic.png'
    
    with PyCallGraph(output=graphviz, config=config):
        main()