はじめに
Pythonのコードからフローチャートを自動生成できる「code2flow」の存在を知りました。
以前に自作したプログラムを確認した際、コメントを見ただけでは、どのようなフローで動作しているのかを把握するのに時間を要していました。プログラムを作成する際に、フローチャートも作成するようにすればよいのですが、プログラムを作成するほうが楽しくて、フローチャートを作成するのを後回しにして、結局作成せずにプログラム作成を終えていました。
Pythonのコードを読み込んで自動でフローチャートを生成するツールがほしい。
Webで検索したり、プログラミングのメンターに相談したところ「code2flow」を教えてもらいました。本ブログでは「code2flow」の下記について整理しました。
- 「code2flow」の使い方
- 「code2flow」のオプション
参考にした書籍
code2flowとは
code2flowは、コードからフローチャートを生成するオープンソースのツールです。code2flowを使用すると、関数、メソッドの呼び出し、どのように相互作用するかを一目で理解することができます。
code2flowを使用してフローチャートを作成すると、下記のような画像を作成することができます。
code2flowのgithubのリンク
scottrogowski/code2flow: Pretty good call graphs for dynamic languages (github.com)
code2flowの実行環境の作成
code2flowを実行するための環境を作成します。
環境構築の作業は下記の3つとなります。
- Pythonの実行環境の構築
- Graphvizのインストール
- code2flowのインストール
1.Pythonの実行環境の構築
Pythonのバージョン3.6以上で実行環境を構築してください。
code2flowのGitHubのリポジトリ内のsetup.pyを確認したところ、下記の記載がありました。
python_requires='>=3.6',
2.Graphvizのインストール
Graphvizは、DOT言語と呼ばれるテキスト形式でグラフやネットワーク構造を描画します。
code2flow が生成する DOT ファイルを Graphviz で処理することにより、コードのフローチャートを生成することができます。
下記のリンクから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 | この関数を中心にグラフのサブセットを出力します。有効な形式には func 、class.func 、file::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」を用いることでファイル名、クラス名の枠を付けづにフローを出力することができます。下記のコマンドはファイル名、クラス名の枠を付けづにフローを出力します。
コメント