動的キー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型が必要な場合に使用します。