JSONからPython Dataclassのデフォルト値付きフィールドへの変換

JSONをPythonに変換する際にdataclassフィールドにデフォルト値を設定する方法を学びます。ミュータブル型のデフォルトファクトリ、フィールド順序ルール、Optionalのデフォルトを解説します。

Dataclasses

詳細な説明

Dataclassのデフォルト値

JSONフィールドが不在の場合やデフォルト値が適切な場合、dataclassフィールドにデフォルト値を設定できます。Pythonでは、デフォルト値のあるフィールドはデフォルト値のないフィールドの後に配置する必要があります。

JSONの例

{
  "name": "Alice",
  "role": "viewer",
  "tags": [],
  "bio": null
}

生成されるPython

from dataclasses import dataclass, field
from typing import Optional

@dataclass
class User:
    name: str
    role: str = "viewer"
    tags: list[str] = field(default_factory=list)
    bio: Optional[str] = None

フィールド順序ルール

Pythonでは、デフォルトのないすべてのフィールドがデフォルトのあるフィールドの前に来る必要があります:

# 有効
@dataclass
class User:
    name: str          # デフォルトなし
    role: str = "viewer"  # デフォルトあり

# 無効 — クラス定義時にTypeError
@dataclass
class User:
    role: str = "viewer"
    name: str          # デフォルトありフィールドの後にデフォルトなし

コンバーターはこの制約を満たすためにフィールドを自動的に並べ替えます。

ミュータブルデフォルトの罠

ミュータブルオブジェクトを直接デフォルト値として使用しないでください:

# 間違い — すべてのインスタンスが同じリストを共有
@dataclass
class User:
    tags: list[str] = []

# 正しい — 各インスタンスに新しいリストが作成される
@dataclass
class User:
    tags: list[str] = field(default_factory=list)

field(default_factory=list) は各新規インスタンスに対して list() を呼び出し、古典的なミュータブルデフォルト引数バグを防ぎます。

NoneデフォルトのOptionalフィールド

JSONで null になりうるフィールドは Optional[T](またはPython 3.10+では T | None)とデフォルト値 None を使用します:

bio: Optional[str] = None

Dictのデフォルトファクトリ

metadata: dict[str, str] = field(default_factory=dict)

デフォルトを使うべき場面

  • 特定のフィールドがオプショナルなAPIレスポンス
  • 適切なフォールバック値を持つ設定オブジェクト
  • フィールドが段階的に設定されるビルダーパターン

ユースケース

ほとんどのフィールドに適切なデフォルト値があるJSONファイルを読み込む設定ローダーを構築しており、dataclassが完全なJSONペイロードと最小限のペイロードの両方で動作するようにしたい場合に使用します。

試してみる — JSON to Python Converter

フルツールを開く