2022年 11月 9日

使用graphviz+pycallgraph绘制python调用关系图

绘制python代码调用关系图

  • 前言
    • 1. 工具安装
    • 1.1 安装graphviz
    • 1.2 安装pycallgraph
    • 2.可视化调用关系
  • 参考文献

前言

一个 python project 中往往包含很多 .py 文件。python文件中又会包含很多函数,函数之间相互传参和调用。如果遇到代码行数很多的情况,我们阅读起来就会有困难。那么有什么办法可以解决这个困难呢?
我们可以考虑采取可视化的方法将代码调用关系用图的方法表示出来。 pycallgraph是一种适用于python代码的动态调用分析工具。当然要想实现可视化还需要安装graphviz。graphviz 是一个图形可视化工具,可以将调用关系表示为图的形式。

1. 工具安装

我们需要首先安装Graphviz,再安装 pycallgraph,否则就会报错。这是由于pycallgraph依赖于dot命令,要想使用 dot 就需要先安装 graphviz。

1.1 安装graphviz

首先给出 graphviz 的官网链接:http://www.graphviz.org/download/
下面给出两种安装方法,推荐使用第一种。
在这里插入图片描述
方法1:进入graphviz官网后,点击 Windows 就自动跳转到 Windows 安装包
在这里插入图片描述
可以根据自己系统的情况选择 win32.exe 或 win64.exe 进行下载。下载好之后进行安装即可。注意:在 install options 界面时记得勾选添加环境变量
如果忘记勾选也不要紧,可以手动设置环境变量,在 path 中添加 graphviz 安装位置下的 bin 路径。例如:C:\Program Files\Graphviz\bin。

方法2:使用Choco命令进行下载
Chocolatey 是一种软件包管理器,只用一行命令就可以实现程序安装。Chocolatey 自身的安装也很方便。使用以管理员身份运行 cmd , 输入以下内容并回车,就可以安装完成。

@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
  • 1
  1. 首先使用 choco info graphviz 查看要安装程序的信息。
    发现有可以安装的 graphviz 包
    在这里插入图片描述
  2. 使用 choco install --yes graphviz 安装 graphviz
    其中 –yes 意味着对 Chocolatey 安装过程的认可,如果不加,Chocolatey 会在安装的每一个步骤前停下来问你是否同意继续。
  3. 安装好后可以使用 choco list --local 查看用 Chocolatey 装了哪些程序
    在这里插入图片描述
    如图所示 graphviz 已经安装好了。
  4. 如果想要卸载 graphviz 可以使用 choco uninstall graphviz 命令。

1.2 安装pycallgraph

还是首先给出 pycallgraph 的官网链接https://pycallgraph.readthedocs.io/en/master/
如果你有多个python环境,请注意在合适的python环境中安装 pycallgraph。
安装命令为:pip install pycallgraph
我在 pytorch 环境下安装了 pycallgraph。如果只有一个python环境,直接 Win + R 使用 cmd 安装即可,命令也是 pip install pycallgraph
在这里插入图片描述

2.可视化调用关系

目前为止,我们已经安装好了所需的工具。下面使用工具可视化 python 函数调用关系。下面给出一个官网的示例。

#!/usr/bin/env python
'''
This example demonstrates a simple use of pycallgraph.
'''
#导入pycallgraph相关包
from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput

# 函数主体
class Banana:

    def eat(self):
        pass


class Person:

    def __init__(self):
        self.no_bananas()

    def no_bananas(self):
        self.bananas = []

    def add_banana(self, banana):
        self.bananas.append(banana)

    def eat_bananas(self):
        [banana.eat() for banana in self.bananas]
        self.no_bananas()


def main():
    graphviz = GraphvizOutput() # 语句1
    # 语句2:在当前目录生成名为 basic.png 的调用关系图
    graphviz.output_file = 'basic.png'

    with PyCallGraph(output=graphviz):	
    #语句3:通过 pycallgraph 可以查看执行下面代码时函数间的调用关系
        person = Person()
        for a in xrange(10):
            person.add_banana(Banana())
        person.eat_bananas()


if __name__ == '__main__':
    main()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

运行结果如下图所示
在这里插入图片描述

参考文献

  1. pygraphviz安装教程(亲测成功)
  2. 像程序员一样安装程序:Chocolatey 初见