@dataclassを使ったデータ構造設計

テクニック

📝 はじめに

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との比較

観点@dataclassdictpandas.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 パーサのような テキスト解析 → 構造化 → 分析 のフローを堅牢かつ効率的に構築できます!

タイトルとURLをコピーしました