Masayan tech blog.

  1. ブログ記事一覧>
  2. Pythonでクラスを定義する際はdataclassesを使用するべし

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

公開日

環境

  • Windows 10
  • Python 3.9.4
  • VSCode

TL;DR

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

具体例

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

余談ですが、__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
    
  ・・・

実装方法としては、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でクラスを定義する際はdataclassesを使用する方法と具体的な実装例について紹介しています。ぜひ参考にしてみてください。