web-dev-qa-db-ja.com

pythonモジュールと関数を含む呼び出しグラフを作成しますか?

タスクを実行するためのスクリプトがたくさんあります。そして、プロジェクトの呼び出しグラフは非常にわかりにくいので、本当に知る必要があります。コードを実行するには余分なハードウェアとソフトウェアが必要なので、コードを実行できません。ただし、その背後にあるロジックを理解する必要があります。したがって、トレースまたはpythonパーサーの代わりにモジュールを使用して呼び出しグラフを作成できるツール(pythonファイルの実行を必要としないツール)があるかどうかを知る必要があります。このようなツールはC用ですが、Python用ではありません。
ありがとうございました。

46
JohnnyDH

私が見つけた最高のツールはpyanと呼ばれ、 元々書かれた によって Edmund Horner彼によって改良された 、そして次に、 与えられた色付け および 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

エドモンド・ホーナーの元のコードは今最もよく見つけられます 彼のgithubリポジトリで 、そして誰かが 両方のバージョンのリポジトリ を作り、そこから Juha Jeronenのバージョンをダウンロードしてください 。両方のリポジトリには他の多くのソフトウェアがあるため、それらの貢献を pyan専用の自分のリポジトリ に結合したクリーンバージョンを作成しました。

35
David Fraser

あなたはpycallgraphをチェックアウトしたいかもしれません:

pycallgraph

また、このリンクでは、より手動のアプローチが説明されています。

生成コールグラフの理解とリファクタリングのPythonコードの生成

26
vkontori

要するに、そのようなツールは存在しません。 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を使用してそのメソッドの1つを呼び出すことに注意してください。これらはいずれも、Pythonの静的な呼び出しグラフを作成するのを非常に困難にする方法です。さらに、モジュールをインポートする方法は、分析するのが困難です。

あなたの最善の策は、コードベースと紙のパッドに座って、手でメモを取り始めることだと思います。これには、コードベースに慣れるという二重の利点があり、解析が難しいシナリオによって簡単にだまされることはありません。

4
Wilduck