Pythonでクラスを定義する際はdataclassesを使用するべし

環境

  • Windows 10
  • Python 3.9.4
  • VSCode

使用するソースコード

以下の公開リポジトリに置いています

GitHub - masayan1126/tao-py-py: 作業自動化用 Python ライブラリ
作業自動化用 Python ライブラリ. Contribute to masayan1126/tao-py-py development by creating an account on GitHub.

TL;DR

  • dataclassesはPython3.7から使用できるデコレーター
  • 主にクラスを定義する際に使用する
  • デコレーターを付けるだけで面倒な__init__()や__repr__()などの特殊メソッドを自動生成してくれる
  • コードが読みやすくなる

具体例

例えば、こういった通知用のクラスがあるとします。(割愛していますが、実際にはinit以降にはrepr()、__eq__()など特殊メソッドが複数定義されています)

masayan
masayan

余談ですが、__repr__()はクラスのオブジェクトをprintなどで出力した際に、クラスのプロパティの値まで出力できるようにするための特殊メソッドです。(__repr__が未実装の場合は、以下のような具合に、インスタンスがそのまま出力されるだけになります)

<XXXXX instance at 0x16c59908>

class Notification:
    def __init__(self, destination_url: str, message: str):
        self._destination_url = destination_url
        self._message = message

  ・・・

    def destination_url(self) -> str:
        return self._destination_url

    def message(self) -> str:
        return self._message

    def set_message(self, message: str):
        self._message = message
        return self

    ・・・

これを、dataclassesを使用すると以下のように変更できます

from dataclasses import dataclass

@dataclass
class Notification:
    _destination_url: str
    _message: str

    def destination_url(self) -> str:
        return self._destination_url

    def message(self) -> str:
        return self._message

    def set_message(self, message: str):
        self._message = message
        return self
    
  ・・・
masayan
masayan

実装方法としては、

dataclassデコレータをクラスに付与し、
型アノテーション付きのクラス変数を定義する

だけでOKです。

また、__init__()は自動生成されますが、初期化の際にエラーハンドリングの処理を追加したい等あれば、自前で定義することも可能です。

dataclassを使うことにより、eq()という特殊メソッドが自動生成され、オブジェクト同士の比較の際に、別インスタンスでも値が同じなら==がTrueとなります

ちなみに、初期値を指定したい場合は少し注意が必要です。

str, intなどのイミュータブルな型の場合はそのまま”=”の後に空文字など指定すれば良いですが、

@dataclass 
class Notification:
  _message: str=""

listやset、dictなどのデフォルト値を設定する場合は、以下のようにdataclasses.fieldとdefault_factoryを使用する必要があります。

class Hoge():
  hoge_list: list = field(default_factory=list)

Python学習におすすめの書籍

独習Python/山田祥寛【3000円以上送料無料】
bookfan 1号店 楽天市場店
¥ 3,300(2022/08/04 17:32時点)
タイトルとURLをコピーしました