データクラスしたい(dataclass

1from dataclasses import dataclass
2
3@dataclass
4class クラス名:
5    変数名:           # 位置引数(必須)
6    変数名:  = 初期値  # オプション引数

C/C++の構造体のように、データ構造を保持するためのクラスを作成する場合に便利なモジュールです。 使い方も簡単で、これまでのクラス定義に@dataclassをデコレータとして追加するだけです。

通常のクラス定義では、__init__でメンバー変数を初期化する必要がありますが、それらを省略できます。 引数が多い場合はとても便利です。

注釈

@dataclassはゆるめのデータクラスを作るのに適しています。変数のバリデーションはなく、あとからメンバー変数を追加することもできます。

設定ファイルを読み込む場合など、変数のバリデーションをしたい場合はpydantic.BaseModelが適しています。

 1from pathlib import Path
 2from dataclasses import dataclass
 3
 4@dataclass
 5class Config:
 6    read_from: str
 7    search_pattern: str
 8
 9    def get_fnames(self):
10        fnames = sorted(Path(self.read_from).glob(self.search_pattern))
11        return fnames
1c = Config(
2    read_from=".",
3    search_pattern="*.csv"
4)
5fnames = c.get_fnames()
6fnames

上記のサンプルは、データを読み込むための設定用クラスを作るときに、よく使っている例です。

初期化したい(__post_init__

 1from pathlib import Path
 2from dataclasses import dataclass
 3
 4@dataclass
 5class Config:
 6    read_from: str
 7    search_pattern: str
 8
 9    def __post_init__(self):
10        self.fnames = self.get_fnames()
11
12    def get_fnames(self):
13        fnames = sorted(Path(self.read_from).glob(self.search_pattern))
14        return fnames

__post_init__でインスタンスを作成したときの挙動を定義できます。

1c = Config(
2    read_from=".",
3    search_pattern="*.csv"
4)
5
6# すでに get_fnames されているので
7# fnames = c.get_fnames() は必要ない
8c.fnames

辞書型にしたい(asdict

 1from dataclasses import dataclass, asdict
 2import pendulum
 3import pandas as pd
 4
 5@dataclass
 6class Quantity:
 7    timestamp: pendulum.datetime
 8    x: float
 9    y: float
10    z: float
11
12q = Quantity(
13    timestamp="測定時刻",
14    x="Xの値",
15    y="Yの値",
16    z="Zの値",
17)
18
19data = pd.DataFrame(asdict(q))

asdict@dataclassクラスを辞書型に変換できます。 pandas.DataFrameとして読み込みたいときに便利です。

リファレンス