0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

(自分用)Python関数設計の5つの方法を比較【Pydantic / dataclass / クラス設計 / attrs / TypedDict】

Last updated at Posted at 2025-05-10

Pythonで「関数の引数設計」をする場合のアプローチ

  1. def を使った通常の関数定義
  2. pydantic.BaseModel を使ったAPI向け設計
  3. @dataclass を使った軽量なモデル
  4. クラス + __init__ によるOOP設計
  5. attrsTypedDict を使った構造化・型安全な設計

この記事では、それぞれのコード例と、特徴・用途を比較した一覧表も載せます。今後も追記予定。

1.通常の関数定義 + if文チェック

example.py
def add(num1: int = 10, num2: int = 10) -> int:
    if isinstance(num1, str) or isinstance(num2, str):
        raise Exception(TypeError, "int型で入力してください")
    return num1 + num2

print(add()) # 出力 20

型ヒントはあるが、チェックは手動。

  • 利点:シンプル。
  • 欠点:バリデーションを毎回書く必要がある。

2.pydantic.BaseModel を使う(FastAPIにも最適)

example.py
from pydantic import BaseModel

class Add(BaseModel):
    num1: int = 10
    num2: int = 10

def add(data: AddModel):
    return data.num1 + data.num2

print(add(Add()))  # 出力 20
  • 利点:バリデーション自動
    • JSONシリアライズ/デシリアライズに強い
    • FastAPIでそのまま利用できる

3.dataclass を使う(標準ライブラリ)

example.py
from dataclasses import dataclass

@dataclass
class Add:
    num1: int = 10
    num2: int = 10

def add(data: AddInt):
    return data.num1 + data.num2

print(add(Add())) # 出力 20
  • 利点:標準ライブラリで軽量。
    • バリデーションは自分で書く必要あり。
    • Pythonicな構造体代替として使える。

4.手動クラス定義 + __init__ を使う(柔軟なOOP)

example.py
class Add:
    def __init__(self):
        self.num1 = 10
        self.num2 = 10

    def add(self):
        return self.num1 + self.num2

print(Add().add()) # 出力 20
  • 利点:継承やメソッド追加などOOP向け
  • 欠点:自由度は高いが冗長

5.attrs を使う(dataclassの上位互換)

example.py
import attr

@attr.s
class AddAttrs:
    num1 = attr.ib(type=int, default=10)
    num2 = attr.ib(type=int, default=10)

def add_attr(data: AddAttrs):
    return data.num1 + data.num2

print(add_attr(AddAttrs()))  # 出力 20
  • 利点:dataclass より柔軟:バリデーションや slots も対応。
    • 軽量・パフォーマンス向上も可能。

6.TypedDict を使う(辞書型の型安全)

example.py
from typing import TypedDict

class AddDict(TypedDict):
    num1: int
    num2: int

def add_dict(data: AddDict):
    return data["num1"] + data["num2"]

print(add_dict({"num1": 5, "num2": 15})) # 出力 20
  • 型付き辞書を扱える(mypyなどで検査可能)
  • 実行時にはバリデーションが効かないので注意

まとめ

方法 構文 バリデーション 初期値 利便性 主な用途
通常関数 def add() 手動(if文) 可能 高い 汎用関数
BaseModel class AddModel(BaseModel) 自動 可能 高い API連携(FastAPI)
dataclass @dataclass なし(手動) 可能 軽量 内部処理/構造体代替
クラス + __init__ class Addnum なし 可能 柔軟 OOP設計/GUI系
attrs @attr.s 自動・柔軟 可能 高い 高機能な構造体
TypedDict class AddDict(TypedDict) 静的(mypy等) なし 軽量 辞書型の構造管理/型安全

使い分けのイメージ

  • FastAPI や API連携が目的なら Pydantic
  • 内部データ構造が目的なら dataclass / attrs
  • 柔軟なOOP設計にはクラス + __init__
  • 構造が辞書ベースなら TypedDict
  • 複雑・多段構造であれば attrs を活用
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?