📝 はじめに
Python で「データをまとめるクラス」を作りたいとき、従来は __init__
を手書きする必要がありました。
しかし Python 3.7 以降では @dataclass
デコレータ を使うことで、シンプルに定義できるようになりました。
この記事では 初心者向けに @dataclass の基本とメリット/デメリット、さらに dict・pandas との比較や実務での使い分けを解説します。
1. @dataclassとは?
@dataclass
を付けると、クラス定義から以下のメソッドが自動生成されます。
__init__
(初期化)__repr__
(表示用文字列)__eq__
(比較演算子)
通常のクラス定義
class TimingPath:
def __init__(self, startpoint, endpoint, slack):
self.startpoint = startpoint
self.endpoint = endpoint
self.slack = slack
def __repr__(self):
return f"TimingPath(startpoint={self.startpoint}, endpoint={self.endpoint}, slack={self.slack})"
@dataclassを使った定義
from dataclasses import dataclass
@dataclass
class TimingPath:
startpoint: str
endpoint: str
slack: float
👉 コード量が大幅に減り、意図が明確になります。
2. メリット
- ✅ コード量削減:
__init__
/__repr__
/__eq__
を自動生成 - ✅ 可読性アップ:データ構造であることが一目でわかる
- ✅ IDE補完や型チェッカー対応:型ヒントと相性が良く、補完や静的解析が効く
- ✅ テストしやすい:オブジェクト同士の比較が簡単
3. デメリット
- ⚠️ 複雑な初期化処理は書きづらい
→__post_init__
を利用する必要あり - ⚠️ 「とりあえず全部dataclass」設計は危険
→ ロジック中心のクラスでは不要 - ⚠️ 継承が絡むと複雑になりやすい
4. 辞書型・pandasとの比較
観点 | @dataclass | dict | pandas.DataFrame |
---|---|---|---|
スキーマ固定 | 高い(型ヒントで定義) | 低い(キー typo に弱い) | 中(列名は固定できるがNaN混入あり) |
可読性 | ◎(意図が明確) | △(何を入れるか不明瞭) | ○(表形式だがコード補完弱め) |
集計・統計 | 弱い | 弱い | ◎(groupby/plot可能) |
補完・静的解析 | ◎ | × | △ |
記述量 | 少 | 最少 | やや多 |
実務での位置付け | 「構造体」用途に最適 | 一時的な入出力に便利 | 集計・可視化に必須 |
5. 実務での使い分け(Timing Reportパーサ例)
1) パース直後は dataclass
@dataclass
class PathPoint:
path_id: int
inst: str
pin: str
incr_ns: float
cap: float | None
tran: float | None
raw: str
👉 スキーマ固定で IDE 補完が効き、テストもしやすい。
2) I/O境界では dict
- JSON書き出しや一時データ受け渡しに便利
- ただし内部処理の中心には使わない方が安全
3) 分析や集計は pandas
import pandas as pd
from dataclasses import asdict
df = pd.DataFrame([asdict(p) for p in points])
df.groupby("inst")["tran"].max()
👉 pandas は集計・統計・可視化で最強。
6. 代表的な落とし穴と対策
- 可変デフォルトの罠
@dataclass class Bad: items: list = [] # 全インスタンスで共有されてしまう
→ 解決策:field(default_factory=list)
を使う - None と NaN の混在(pandas変換時)
→fillna()
やdtype
指定で型を揃える - dict のキー typo
→ dataclass に早めに変換する
✅ まとめ
- @dataclass は「データをまとめるクラス」に最適
- メリット:コード短縮・可読性・型チェック・補完
- デメリット:複雑な初期化や安易な濫用に注意
- 使い分けの指針
- データ保持 =
@dataclass
- 入出力や一時データ =
dict
- 集計/分析 =
pandas
- データ保持 =
👉 これらを組み合わせると、Timing Report パーサのような テキスト解析 → 構造化 → 分析 のフローを堅牢かつ効率的に構築できます!