動的キーJSONオブジェクトからPythonのdict型への変換

動的または未知のキーを持つJSONオブジェクトをPythonのdict[str, T]型アノテーションに変換する方法を学びます。型付きdict、反復、型の絞り込みを解説します。

Type Annotations

詳細な説明

PythonのdictによるJSONの動的キーの処理

JSONオブジェクトのキーが固定でない場合(例:ロケールコード、ユーザーID、メトリクス名)、dataclassフィールドとしてモデル化できません。代わりに、Pythonの dict 型にマッピングします。

JSONの例

{
  "translations": {
    "en": "Hello",
    "ja": "こんにちは",
    "es": "Hola"
  },
  "scores": {
    "user_001": 95,
    "user_002": 82
  }
}

生成されるPython

from dataclasses import dataclass

@dataclass
class Data:
    translations: dict[str, str]
    scores: dict[str, int]

値型が混在する場合

値が均一でない場合はunion型を使用します:

{
  "settings": {
    "theme": "dark",
    "fontSize": 14,
    "autoSave": true
  }
}
from typing import Any

@dataclass
class Config:
    settings: dict[str, Any]

より正確な型付けにはunionを使用します:

from typing import Union

settings: dict[str, Union[str, int, bool]]
# Python 3.10+:
settings: dict[str, str | int | bool]

型付きdictの反復

for locale, text in data.translations.items():
    print(f"{locale}: {text}")
    # mypyはlocaleがstr、textがstrであることを認識

dict vs dataclassの判断

  • 既知の固定キー — dataclassを使用。各キーが型付きフィールドになる。
  • 動的な未知キーdict[str, T] を使用。キーがデータ駆動。
  • 混合 — 固定フィールドにはdataclass、動的部分にはdictフィールドを使用。

ネストされたdict

# JSON: {"matrix": {"row1": {"col1": 1, "col2": 2}}}
matrix: dict[str, dict[str, int]]

型構文

Pythonバージョン 構文
3.7-3.8 Dict[str, int]typing から)
3.9+ dict[str, int](組み込み)

ユースケース

CMSからロケールコードがキーで翻訳文字列が値のtranslationsオブジェクトを受け取り、任意のロケールを許可しつつ値の型を強制するdict型が必要な場合に使用します。

試してみる — JSON to Python Converter

フルツールを開く