JSON文字列値からPython Enumへの変換
固定セットの文字列値を持つJSONフィールドをPython Enumクラスに変換する方法を学びます。StrEnum、auto()、dataclassやPydanticとの統合を解説します。
Advanced Patterns
詳細な説明
JSONのカテゴリ値をPython Enumとして表現
JSONフィールドが固定セットの値のみを取る場合(status、role、priorityなど)、Python Enumに変換することで型安全性を提供し、無効な値を防ぎます。
JSONの例
{
"id": 1,
"status": "active",
"role": "admin",
"priority": "high"
}
生成されるPython
from dataclasses import dataclass
from enum import StrEnum
class Status(StrEnum):
ACTIVE = "active"
INACTIVE = "inactive"
PENDING = "pending"
class Role(StrEnum):
ADMIN = "admin"
EDITOR = "editor"
VIEWER = "viewer"
class Priority(StrEnum):
HIGH = "high"
MEDIUM = "medium"
LOW = "low"
@dataclass
class Ticket:
id: int
status: Status
role: Role
priority: Priority
なぜStrEnumなのか?
StrEnum(Python 3.11+)はenumメンバーを文字列としても機能させます:
Status.ACTIVE == "active" # True
str(Status.ACTIVE) # "active"
json.dumps({"status": Status.ACTIVE}) # '{"status": "active"}'
これによりカスタムエンコーダーなしでJSONシリアライゼーションが機能します。
Python 3.11未満の場合
from enum import Enum
class Status(str, Enum):
ACTIVE = "active"
INACTIVE = "inactive"
PENDING = "pending"
str と Enum の両方を継承することで同じ動作を実現します。
Pydanticとの統合
Pydanticはenum値を自動的にバリデーションします:
from pydantic import BaseModel
class Ticket(BaseModel):
id: int
status: Status
# 有効
Ticket(id=1, status="active") # Pydanticが文字列をenumに変換
# 無効 — ValidationErrorが発生
Ticket(id=1, status="unknown")
整数Enum
数値カテゴリ値の場合:
from enum import IntEnum
class Priority(IntEnum):
LOW = 1
MEDIUM = 2
HIGH = 3
Enumを使うべき場面
- 固定セットの値 — ステータス、ロール、優先度、カテゴリ。
- 型安全性 — 任意の文字列の割り当てを防ぎます。
- 自動補完 — IDEが有効な値を提案します。
- 網羅的マッチング —
match文が未処理のケースについて警告します(Python 3.10+)。
ユースケース
チケット管理システムを構築しており、status、role、priorityを特定の値に制約する必要があり、mypyで開発時に無効な代入を検出したい場合に使用します。