JavaScriptを有効にしてください

Pythonのクラス図をPyreverseで自動生成する

 ·   5 min read

はじめに

Pythonで作成したコードのクラス図を、Pyreverseを使って自動生成する方法を解説します。クラス図とは、クラスの属性やメソッド、およびクラス間の関係を示す以下のような図のことです。

継承のクラス図

この記事で検証した環境は以下の通りです。

  • OS: Windows 10 Home
  • Python 3.11.6
  • Pylint 3.0.2
  • Graphviz(Pythonライブラリ) 0.20.1
  • Graphviz(本体) 2.46.1

PyreverseはPylintというライブラリに含まれています。また、Graphvizはクラス図を画像として出力するために必要であり、Windows用のソフト本体と、Pythonのインターフェースとしてのライブラリの両方をインストールします。

この記事はPython Advent Calendar 2023 (Qiita) 13日目の記事です。

インストール

Pythonは既にインストールされていることを前提とします。以下のコマンドを実行して、Pylint(Pyreverseも含まれています)とGraphviz(Pythonライブラリ)をインストールします。

1
2
> pip install pylint
> pip install graphviz

次に、Graphvizの公式サイトからインストーラを入手して、Graphvizの本体をインストールします。
https://graphviz.org/download/

インストール中にパスを通すか聞かれるので、通しておきます。以下の画面で"Add Graphviz to the system PATH for all users"または"current user"を選択します。

Graphvizのインストール画面

Graphvizのインストール後、PowerShellまたはコマンドプロンプトで以下のコマンドを実行します。Graphvizにパスが通っていれば、バージョン番号が表示されます。

1
2
> dot -V
dot - graphviz version 2.46.0 (20210118.1747)

クラス図の作成例

まず、クラスが1つだけのPythonスクリプトを例に、Pyreverseを使ってクラス図を出力します。以下のスクリプトでは、Personというクラスが定義されています。これをsingle_class.pyという名前を付けて保存します。

1
2
3
4
5
6
class Person:
    def __init__(self, name):
        self.name = name

    def greet(self):
        print(f"I'm {self.name}.")

次に、single_class.pyと同じディレクトリで以下のコマンドを実行します。

1
2
> pyreverse -o png -p single single_class.py
Format png is not supported natively. Pyreverse will try to generate it using Graphviz...

ここで、-oオプションで出力形式、-pオプションで出力するファイル名の接尾辞を指定します。コマンドの実行後、以下のクラス図がclasses_single.pngというファイル名で出力されます。

クラス図

上から順に、クラスの以下の情報が表示されています。

  • クラス名
  • 属性
  • メソッド

クラス間の関係

クラス間の関係として継承(汎化)、集約、コンポジションについて、それぞれクラス図として出力する例を示します。

継承(汎化)

継承とは、あるクラスの特性(属性やメソッドなど)を別のクラスに引き継ぐことです。以下のスクリプトをinheritance.pyとして保存します。先ほどのPersonクラスを継承したEmployeeクラスを定義しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Person:
    def __init__(self, name):
        self.name = name

    def greet(self):
        print(f"I'm {self.name}.")

class Employee(Person):
    def __init__(self, name, company):
        super().__init__(name)
        self.company = company

    def greet2(self):
        print(f"I'm {self.name} from {self.company}.")

以下のコマンドを実行して、クラス図を出力します。

1
> pyreverse -o png -p inheritance inheritance.py

PersonクラスとEmployeeクラスが白い三角の矢印で結ばれており、継承(汎化)関係が出力されています。

継承のクラス図

集約

集約とは、以下のようなクラス間の関係です。

  • あるクラスが別のクラスの「部分」として表される
  • 全体のインスタンスが破棄されても、部分インスタンスが破棄されるとは限らない

以下のスクリプトaggregation.pyを作成します。Companyクラスのpresident属性はPersonインスタンスとなります。すなわち、PersonクラスはCompanyクラスの「部分」となります。また、型ヒントを使って、person引数はPersonインスタンスであることを示しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Person:
    def __init__(self, name):
        self.name = name

    def greet(self):
        print(f"I'm {self.name}.")

class Company:
    def __init__(self, company_name, person:Person):
        self.company_name = company_name
        self.president = person

以下のコマンドを実行して、クラス図を出力します。

1
> pyreverse -o png -p aggregation aggregation.py

PersonクラスとCompanyクラスが白い菱形の矢印で結ばれており、集約関係が出力されています。矢印の緑の文字は、PersonクラスがCompanyクラスのpresident属性になることを示しています。

集約のクラス図

コンポジション

コンポジションとは、以下のようなクラス間の関係です。

  • あるクラスが別のクラスの「部分」として表される
  • 全体のインスタンスが破棄されると、部分インスタンスも破棄される

以下のスクリプトcomposition.pyを作成します。Personインスタンスの作成時に、Headインスタンス (Person.head) も作成されます。また、Personインスタンスが破棄されるときにPerson.headも破棄されるため、HeadクラスはPersonクラスのコンポジションとなります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Head:
    def __init__(self, wisdom:str):
        self.wisdom = wisdom

class Person:
    def __init__(self, name:str, wisdom:str):
        self.name = name
        self.head = Head(wisdom)

    def greet(self):
        print(f"I'm {self.name}.")

以下のコマンドを実行して、クラス図を出力します。

1
> pyreverse -o png -p composition composition.py

PersonクラスとHeadクラスが黒い菱形の矢印で結ばれており、コンポジション関係が出力されています。矢印の緑の文字は、HeadクラスがPersonクラスのhead属性になることを示しています。

コンポジションのクラス図

参考

シェアする

Helve
WRITTEN BY
Helve
関西在住、電機メーカ勤務のエンジニア。X(旧Twitter)で新着記事を配信中です

サイト内検索