型ヒント付きプレーンなPython DictへのJSONパース

最もシンプルなJSON-to-Python変換:型アノテーション付きプレーンなdictへのJSONパースを学びます。json.loads()、typingパターン、dictで十分な場合を解説します。

Serialization

詳細な説明

最もシンプルな変換:JSONからDictへ

dataclassやPydanticを使う前に、型アノテーション付きdictで十分かどうかを検討してください。Pythonの組み込み json.loads() はプレーンなdictを返し、TypedDictやシンプルな型ヒントでアノテーションできます。

JSONの例

{
  "name": "Alice",
  "age": 30,
  "active": true
}

プレーンなdict

import json

data: dict[str, Any] = json.loads(raw_json)
print(data["name"])  # "Alice"

TypedDictで安全に

from typing import TypedDict

class UserDict(TypedDict):
    name: str
    age: int
    active: bool

data: UserDict = json.loads(raw_json)
print(data["name"])  # 型チェッカーはこれがstrであることを認識

json.loads()の型マッピング

JSON Python
{} dict
[] list
"string" str
123 int
3.14 float
true/false bool
null None

Dictで十分な場合

  • クイックスクリプト — クラスのオーバーヘッドが不要。
  • パススルー — JSONを受け取り、処理せずに転送する。
  • 動的キー — キーがスキーマ駆動ではなくデータ駆動。
  • 相互運用 — サードパーティのコードがプレーンなdictを期待する。

アップグレードすべき場面

以下の場合はdataclassやPydanticに移行します:

  • 属性アクセスが必要(user["name"] ではなく user.name)。
  • バリデーションが必要(Pydantic)。
  • データオブジェクトにメソッドが必要。
  • 構造が複雑で、dictのネストが追いにくくなっている。

パフォーマンス

json.loads() からdictへは最速のデシリアライゼーションパスです。dataclass構築はオーバーヘッドを追加します。Pydanticバリデーションはさらに追加します。数百万レコードを処理する高スループットパイプラインでは、プレーンなdictが正しい選択かもしれません。

型安全なアクセス

from typing import Any

def get_name(data: dict[str, Any]) -> str:
    name = data.get("name")
    if not isinstance(name, str):
        raise ValueError("name must be a string")
    return name

TypedDictがない場合、型安全性のためにランタイムチェックが必要です。

ユースケース

JSONファイルを読み込み、pandasや他のライブラリ(プレーンdictを期待する)にデータを渡す簡易データ処理スクリプトを書いており、最小限のオーバーヘッドが必要な場合に使用します。

試してみる — JSON to Python Converter

フルツールを開く