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"

strEnum の両方を継承することで同じ動作を実現します。

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で開発時に無効な代入を検出したい場合に使用します。

試してみる — JSON to Python Converter

フルツールを開く