Pythonで「関数の引数設計」をする場合のアプローチ
-
def
を使った通常の関数定義 -
pydantic.BaseModel
を使ったAPI向け設計 -
@dataclass
を使った軽量なモデル - クラス +
__init__
によるOOP設計 -
attrs
やTypedDict
を使った構造化・型安全な設計
この記事では、それぞれのコード例と、特徴・用途を比較した一覧表も載せます。今後も追記予定。
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
を活用