在python中建立包含模块和函数的调用图?

问题描述 投票:48回答:4

我有一堆脚本来执行任务。我真的需要知道该项目的调用图,因为它非常令人困惑。我无法执行代码,因为它需要额外的硬件和软件来执行。但是,我需要了解其背后的逻辑。因此,我需要知道是否有一个工具(不需要执行任何python文件),可以使用模块而不是跟踪或python解析器来构建调用图。我有针对C的此类工具,但没有针对python的此类工具。谢谢。

python function static module call-graph
4个回答
36
投票

我找到的最好的工具称为pyanoriginally written分别为Edmund Hornerimproved by him,然后为given colorization和其他功能,分别为Juha Jeronen。该版本具有有用的命令行选项:

Usage: pyan.py FILENAME... [--dot|--tgf]

Analyse one or more Python source files and generate an approximate call graph
of the modules, classes and functions within them.

Options:
  -h, --help           show this help message and exit
  --dot                output in GraphViz dot format
  --tgf                output in Trivial Graph Format
  -v, --verbose        verbose output
  -d, --defines        add edges for 'defines' relationships [default]
  -n, --no-defines     do not add edges for 'defines' relationships
  -u, --uses           add edges for 'uses' relationships [default]
  -N, --no-uses        do not add edges for 'uses' relationships
  -c, --colored        color nodes according to namespace [dot only]
  -g, --grouped        group nodes (create subgraphs) according to namespace
                       [dot only]
  -e, --nested-groups  create nested groups (subgraphs) for nested namespaces
                       (implies -g) [dot only]

这是运行pyan.py --dot -c -e pyan.py | fdp -Tpng的结果:

pyan's output on itself

埃德蒙·霍纳(Edm Horner)的原始代码现在最好是in his github repository,并且有人也从repository with both versions处创建了download Juha Jeronen's version。我制作了一个干净的版本,将它们的贡献合并到my own repository just for pyan中,因为两个存储库都有很多其他软件。


26
投票

您可能要签出pycallgraph:

pycallgraph

也在此链接中描述了更手动的方法:

generating-call-graphs-for-understanding-and-refactoring-python-code


6
投票

简而言之,不存在这样的工具。 Python的语言过于动态,无法在不执行代码的情况下生成调用图。

这里有一些代码清楚地展示了python的一些非常动态的功能:

class my_obj(object):
    def __init__(self, item):
        self.item = item
    def item_to_power(self, power):
        return self.item ** power

def strange_power_call(obj):
    to_call = "item_to_power"
    return getattr(obj, to_call)(4)

a = eval("my" + "_obj" + "(12)")
b = strange_power_call(a)

请注意,我们正在使用eval创建my_obj的实例,还使用getattr调用其方法之一。这两种方法都使得为python创建静态调用图变得极为困难。此外,还有各种各样难以分析的模块导入方式。

我认为您最好的选择是坐在代码库和纸上,然后开始手工做笔记。这将具有使您更熟悉代码库的双重好处,并且不会因难以解析的场景而容易被欺骗。


0
投票

SourceTrail将在这里为您提供帮助。 https://www.sourcetrail.com/

Sourcetrail是一个免费的开放源代码跨平台源浏览器,可帮助您提高不熟悉的源代码的工作效率。支持C,C ++,Java和Python

https://github.com/CoatiSoftware/Sourcetrail

enter image description here

这里是文档的链接

https://www.sourcetrail.com/documentation/

请注意,Python支持是相对较新的,所以请不要指望它能完美运行。

© www.soinside.com 2019 - 2024. All rights reserved.