作为一个对自己代码负责人的开发者,代码结构是否清晰合理可以直接体现出开发者的设计思路与水 准;而这种结构的合理性往往使用分层的设计思想,让每个层的模块各司其职,做到符合设计的同时,也便于管理。在Java中,有工具能画出各个包之间的依赖关系,例如下面这样的图。

Java诞生背景便是为解决企业开发 管理需求 通点而随之而来各种面向企业设计思路的解决方案与治理思想,所以在项目的框架结构,如何组织上有较为明确的规范与标准。例如近年来的面向领域设计思想。

与Java不同,Python从诞生到如今约20年,尤其是在 web 开发领域并没有形成一种较为统一的代码规范与风格,往往只能参照 MVC 这种相对赢弱(取决于如何理解)的套路。一个 Python 的 web 项目在经过几年,几代人的开发后,结构往往无法符合设计者的初衷;甚至最初设计项目代码结构的人,也没考虑过代码应该如何组织。

那么,Python 是否有这样的工具来帮助整理代码模块间的依赖关系呢?

Snakefood

Snakefood1 是一块基于 Python 源代码语法树解析写成的工具,能够满足上面提到的要求。

具有以下特点:

  • 使用 AST 解析 Python 文件,保证稳定运行
  • 不加载额外模块
  • 支持多个文件、目录等
  • 不需要额外配置,默认即可使用
  • 通过提供多个不同功能的命令,符合 UNIX 设计思想

截至笔者写文时, snakefood 尚不支持在 Python 3.x 环境下运行。不过 可以用来分析 Python3 的项目。

# snakefood 目前只支持运行在 2.x 分支 **但可以用来检测 Python3 的项目,只要后者能兼容 2.7**
$ virtualenv -p python2.7 local
# 安装 snakefood
$ local/bin/pip install snakefood
# 运行 snakefood 得到依赖关系数据
$ local/bin/sfood /path/to/module
$ 将依赖数据转化为图表,通过 graphviz 画成图
$ local/bin/sfood /path/to/module | local/bin/sfood-graph | dot -T svg -o dep.svg

生成的依赖关系数据类似如下

# 前面是源代码文件,后面是依赖,一行一个
(('/home/momoka/src/ploceus', 'ploceus/tools/files.py'), (None, None))
(('/home/momoka/src/ploceus', 'ploceus/tools/files.py'), ('/home/momoka/src/ploceus', 'ploceus/colors.py'))
(('/home/momoka/src/ploceus', 'ploceus/tools/files.py'), ('/home/momoka/src/ploceus', 'ploceus/helper.py'))
(('/home/momoka/src/ploceus', 'ploceus/tools/files.py'), ('/home/momoka/src/ploceus', 'ploceus/logger.py'))
(('/home/momoka/src/ploceus', 'ploceus/tools/files.py'), ('/home/momoka/src/ploceus', 'ploceus/runtime.py'))
(('/home/momoka/src/ploceus', 'ploceus/tools/files.py'), ('/usr/lib64/python2.7', 'hashlib.py'))
(('/home/momoka/src/ploceus', 'ploceus/tools/files.py'), ('/usr/lib64/python2.7', 'os.py'))
(('/home/momoka/src/ploceus', 'ploceus/tools/files.py'), ('/usr/lib64/python2.7', 'tempfile.py'))
(('/home/momoka/src/ploceus', 'ploceus/tools/group.py'), (None, None))
(('/home/momoka/src/ploceus', 'ploceus/tools/group.py'), ('/home/momoka/src/ploceus', 'ploceus/exceptions.py'))

Flask 的关系图

检测的版本为 74691fbe0192de1134c93e9821d5f8ef65405670

  • SVG格式:
  • PNG格式:

我们项目的关系图

这是经过大约2年以上开发的鄙厂的图,细节就不能透露更多啦。不过从图上密密麻麻的线与混杂的环形就可以推断出,这样的结果一定是存在不合理的依赖关系的2

以后笔者再整理一篇如何应用依赖关系图,通过重构,让代码结构更合理。

__END__


  1. http://furius.ca/snakefood/

  2. https://stackoverflow.com/questions/894864/circular-dependency-in-python