Pythonコードのフローチャートを自動生成する(code2flowの使い方)

Python

はじめに

Pythonのコードからフローチャートを自動生成できる「code2flow」の存在を知りました。

以前に自作したプログラムを確認した際、コメントを見ただけでは、どのようなフローで動作しているのかを把握するのに時間を要していました。プログラムを作成する際に、フローチャートも作成するようにすればよいのですが、プログラムを作成するほうが楽しくて、フローチャートを作成するのを後回しにして、結局作成せずにプログラム作成を終えていました。

Pythonのコードを読み込んで自動でフローチャートを生成するツールがほしい。

Webで検索したり、プログラミングのメンターに相談したところ「code2flow」を教えてもらいました。本ブログでは「code2flow」の下記について整理しました。

  • 「code2flow」の使い方
  • 「code2flow」のオプション

参考にした書籍

bookfan 1号店 楽天市場店
¥3,190 (2024/12/02 06:43時点 | 楽天市場調べ)

code2flowとは

code2flowは、コードからフローチャートを生成するオープンソースのツールです。code2flowを使用すると、関数、メソッドの呼び出し、どのように相互作用するかを一目で理解することができます。

code2flowを使用してフローチャートを作成すると、下記のような画像を作成することができます。

code2flowのgithubのリンク

scottrogowski/code2flow: Pretty good call graphs for dynamic languages (github.com)

code2flowの実行環境の作成

code2flowを実行するための環境を作成します。
環境構築の作業は下記の3つとなります。

  1. Pythonの実行環境の構築
  2. Graphvizのインストール
  3. code2flowのインストール

1.Pythonの実行環境の構築

Pythonのバージョン3.6以上で実行環境を構築してください。

code2flowのGitHubのリポジトリ内のsetup.pyを確認したところ、下記の記載がありました。

 python_requires='>=3.6',

2.Graphvizのインストール

Graphvizは、DOT言語と呼ばれるテキスト形式でグラフやネットワーク構造を描画します。
code2flow が生成する DOT ファイルを Graphviz で処理することにより、コードのフローチャートを生成することができます。

下記のリンクからGraphvizをダウンロードしてインストールしてください。

Download | Graphviz

インストール画面で「PATH」の設定を選択する画面が出てきます。
「Add Graphviz to the system PATH for all users」を選択してください。

3.code2flowのインストール

Pythonの仮想環境を起動したあとに、pipコマンドでインストールします。

(venv)$ pip install code2flow

基本的な使い方

ここでは、code2flowの基本的な使い方をサンプルコードを用いて説明します。

フロー出力用のサンプルコード

フローチャートを作成対象のサンプルコードは下記となります。サンプルコードは2つ用意します。

<ファイル名:sample01.py>

import sample02

def test01_func():
    tmp = test02_func()
    tmp = test03_func()
    tmp = test04_func()
    tmp = sample02.test10_func()
    return 'tmp'

def test02_func():
    tmp = test06_func()
    return 'tmp'

def test03_func():
    return 'tmp'

def test04_func():
    tmp = test05_func()
    return 'tmp'

def test05_func():
    tmp_class = Test01Class()
    tmp = tmp_class.test07_func()
    return 'tmp'

def test06_func():
    return 'tmp'

class Test01Class:
    def test07_func(self):
        tmp = self.test08_func()
        tmp = self.test09_func()
        return 'tmp'

    def test08_func(self):
        return 'tmp'

    def test09_func(self):
        return 'tmp'

if __name__ == "__main__":
    tmp = test01_func()

<ファイル名:sample02.py>

def test10_func():
    tmp = test11_func()
    tmp = test12_func()
    return 'tmp'

def test11_func():
    tmp = test13_func()
    return 'tmp'

def test12_func():
    return 'tmp'

def test13_func():
    tmp = test14_func()
    return 'tmp'

def test14_func():
    return 'tmp'

フローチャート作成の実行

code2flowをインストールした仮想環境で下記のコマンドを実行します。

(venv)$ code2flow プログラムファイル名

コマンドを実行するとフローチャートを「out.png」の名前で出力します。
ファイルの形式はPNGとなります。

(venv)$ code2flow sample01.py

「out.png」を開くと下記のフローチャートを確認することができます。

別のプログラムファイルをインポートしている場合は、code2flowのコマンドの引数で2つのプログラムファイルを設定します。

(venv)$ code2flow sample01.py sample02.py

「out.png」を開くと下記のフローチャートを確認することができます。

オプション

code2flowのオプションの日本語訳をまとめました。

オプション 説明
-h, –help ヘルプメッセージを表示して終了します。
–output OUTPUT, -o OUTPUT 出力ファイルのパス。サポートされるタイプは (‘png’, ‘svg’, ‘dot’, ‘gv’, ‘json’) です。(デフォルト: out.png)
–language {py,js,rb,php} この言語を処理し、他のファイルは無視します。省略した場合は、最初のソースファイルの拡張子を使用します。(デフォルト: なし)
–target-function この関数を中心にグラフのサブセットを出力します。有効な形式には funcclass.funcfile::class.func が含まれます。–upstream-depth および/または –downstream-depth が必要です。(デフォルト: なし)
–upstream-depth –target-function の上流のノードを n 個含めます。(デフォルト: 0)
–downstream-depth –target-function の下流のノードを n 個含めます。(デフォルト: 0)
–exclude-functions 出力から関数を除外します。カンマ区切り。(デフォルト: なし)
–exclude-namespaces 出力から名前空間(クラス、モジュールなど)を除外します。カンマ区切り。(デフォルト: なし)
–include-only-functions 出力に関数のみを含めます。カンマ区切り。(デフォルト: なし)
–include-only-namespaces 出力に名前空間(クラス、モジュールなど)のみを含めます。カンマ区切り。(デフォルト: なし)
–no-grouping 関数を名前空間にグルーピングする代わりに、関数を浮かせます。(デフォルト: False)
–no-trimming 何かに接続しているかどうかに関わらず、すべての関数/名前空間を表示します。(デフォルト: False)
–hide-legend デフォルトでは、Code2flowは小さな凡例を生成します。このフラグはそれを非表示にします。(デフォルト: False)
–skip-parse-errors デフォルトでは、Code2flowは小さな凡例を生成します。このフラグはそれを非表示にします。(デフォルト: False)
–skip-parse-errors 言語パーサが失敗するファイルをスキップします。(デフォルト: False)
–source-type {script,module} jsのみ。ソースをスクリプト(commonJS)またはモジュール(es6)として解析します。(デフォルト: script)
–ruby-version RUBY_VERSION rubyのみ。どのrubyバージョンを解析するか?これはruby-parseに直接渡されます。25、27、31などの数字を使用してください。(デフォルト: 27)

フローの出力形式の設定したい場合

「-o」を用いることで出力形式を設定してフローを出力することができます。出力できる形式は ‘png’, ‘svg’, ‘dot’, ‘gv’, ‘json’です。下記のコマンドはSVG形式でフローを出力します。

(venv)$ code2flow -o out.svg sample01.py sample02.py

指定した関数を中心にしてフローを出力したい場合

「–target-function」を用いることで指定した関数を中心にフローを出力することができます。使用する際は、「–downstream-depth」(下流)あるいは「–upstream-depth」(上流)を合わせて使用する必要があります。下記のコマンドは指定した関数の下流1段目までのフローを出力します。

(venv)$ code2flow --target-function test01_func --downstream-depth 1 sample01.py sample02.py

下記のコマンドは指定した関数の上流1段目までのフローを出力します。

(venv)$ code2flow --target-function test01_func --upstream-depth 1 sample01.py sample2.py

「–downstream-depth」と「–upstream-depth」を同時に使用することもできます。下記のコマンドは指定した関数の上流1段目と下流1段目までのフローを出力します。

(venv)$ code2flow --target-function test01_func --downstream-depth 1 --upstream-depth 1 sample01.py sample02.py

指定した関数を除外したい場合

「–exclude-functions」を用いることで指定した関数を除外してフローを出力することができます。下記のコマンドは指定した関数を除外してフローを出力します。

(venv)$ code2flow --exclude-functions test02_func,test12_func sample01.py sample02.py

指定したクラス、モジュールを除外する

「–exclude-namespaces」を用いることで指定したクラス、モジュールを除外してフローを出力することができます。下記のコマンドは指定したクラスを除外してフローを出力します。

ファイル名、クラス名で枠を付けたくない場合

「–no-grouping」を用いることでファイル名、クラス名の枠を付けづにフローを出力することができます。下記のコマンドはファイル名、クラス名の枠を付けづにフローを出力します。

コメント

タイトルとURLをコピーしました