在 python 中构建一个调用图,包括模块和函数? [关闭]

Posted

技术标签:

【中文标题】在 python 中构建一个调用图,包括模块和函数? [关闭]【英文标题】:Build a Call graph in python including modules and functions? [closed] 【发布时间】:2012-12-07 10:49:05 【问题描述】:

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

【问题讨论】:

【参考方案1】:

简而言之,不存在这样的工具。 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 创建静态调用图变得极其困难。此外,还有各种难以分析的模块导入方式。

我认为最好的办法是坐下来拿着代码库和一张纸,然后开始手写笔记。这将有双重好处,让您更熟悉代码库,并且不会轻易被难以解析的场景所欺骗。

【讨论】:

我知道。最多可以在模块中搜索importdeffunc() 语句。我想我会写一个程序来做到这一点。当然,它只适用于简单源代码。 只有非常简单的。您还需要解析 cmets、strings 和 docstrings,以免被它们愚弄。我已经编辑了我的答案,以包括我认为你应该做的事情。 是的,我是手动做的...有 14 个引用的脚本...祝我好运:) @Wilduck 静态分析器可能很有用,但并不完整。任何语言都可以混淆它的调用图。例如,我可以使用 C++ 中的字典来查找函数指针并调用它们。静态调用图是在深入研究新代码库之前获得高级概述的快速方法。 Questions 说 OP 有这样一个 C.Gee 的工具,这怎么可能? C 有函数指针 ...【参考方案2】:

您可能想查看 pycallgraph:

pycallgraph

此链接中还描述了一种更手动的方法:

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

【讨论】:

是的,我在研究过程中看到了这个页面,但我正在寻找一个“专业”的解决方案。恐怕这种东西不存在……新的创业想法?呵呵 不幸的是,Pycallgraph 不能很好地消化软件包 pycallgraph 正在运行代码,这是他要求不要做的。 pyan 进行静态分析(请参阅下面的答案) 第二个链接失效 pycallgraph 现已无人维护【参考方案3】:

我发现的最好的工具是pyan,是Edmund Horner 的originally written,improved 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的结果:

Edmund Horner 的原始代码现在最好找到 in his github repository,并且有人还制作了 repository with both versions,您可以从那里 download Juha Jeronen's version。我制作了一个干净的版本,将他们的贡献合并到my own repository just for pyan,因为两个存储库都有很多其他软件。

【讨论】:

@DavidFraser 是否与 Python 3.x 兼容? @AlexanderReshytko 不幸的是没有。我已经将一个名为 py3-compat 的分支推送到我的 github 存储库,它进行了最小的更改。但这使用了 compiler 模块,该模块在 Python 3 中被删除。代码需要重新构造以使用 ast.NodeVisitor 子类;这应该不会太难,但我现在没有时间去做。 (它仍然与 Python 2.6+ 兼容) 给关注此的任何人的说明;包括 Technologicat 在内的各种用户现在都贡献了 Python 3 支持 这很好用。我在 Windows 上,我发现它有助于创建一个执行 python "C:\path\to\pyan.py" %1 --uses --defines --colored --grouped --annotated --dot >pyan_output.dot && clip < pyan_output.dot 的 bash 命令,这样我就可以粘贴到 webgraphviz.com 并查看输出。感谢您帮助创建并保持更新! 截至现在,似乎维护得最好的fork是github.com/Technologicat/pyan,虽然相关的PyPI包pypi.org/project/pyan3已经有一段时间没有更新了。跨度> 【参考方案4】:

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

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

https://github.com/CoatiSoftware/Sourcetrail

这是文档的链接

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

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

【讨论】:

【参考方案5】:

我还在https://github.com/zw-normal/pycallgraph 写了一个小工具。 代码的概念很容易理解和使用,但它只提供了有限的信息,还需要另一个 IDE 才能更好地理解。

【讨论】:

【参考方案6】:

您应该查看PyCG,这是我们创建的peer reviewed Python 调用图生成器,它可以处理 Python 的大部分功能,包括高阶函数、类、生成器等。

【讨论】:

【参考方案7】:

我找到的 pyan3 的工作版本是 1.1.1 (pip install pyan3==1.1.1),它的文档是 here

【讨论】:

【参考方案8】:

我最近(2021 年)在寻找这样的工具,发现 code2flow 似乎正在积极维护。

【讨论】:

以上是关于在 python 中构建一个调用图,包括模块和函数? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

python控制流-导入模块

在编译时提供函数元数据的大多数 Pythonic 方式?

Python 模块应该如何使用代码生成?

python之路第五天

在python程序中,一个源代码文件中,在函数体中声明的变量(包括函数参数)称?

python中的time模块