100% ローカル — データがブラウザの外に出ることはありません

JSONをPythonに変換|3つの書き方から選んで出力する

JSONのサンプルをPythonのクラスに変換します。Pydantic、dataclass、TypedDict から、プロジェクトで使っている書き方を選んで、そのまま models.py に貼れます。

高速 プライベート Cookieゼロ
スタイル

JSON 入力

Python 出力

このツールの動作

JSON の標本が Python のクラスになります。オブジェクト一つにつき一つです。

{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
from pydantic import BaseModel, Field


class Address(BaseModel):
    city: str


class Root(BaseModel):
    id: int
    first_name: str = Field(alias="firstName")
    address: Address

子が先に宣言されます。あるクラスが別のクラスで項目に注釈を付ける前に、そのクラスが存在している必要があるからです。出力は現代の Python を想定しています。list[str] や int | str をそのまま書くので、3.10 以降が要ります。

三つの書き方、三つの代償

書き方得られるもの代償
Pydantic境界での検証、名前を変えた鍵の別名依存が一つ増え、素のオブジェクトではなくなる
dataclass単純な入れ物、標準ライブラリだけ検証なし、名前を変えた鍵の別名もなし
TypedDictすでにある辞書への注釈実行時には何も起きない——つまり検査もされない

構造は三つとも同じです。変わるのは、その型があなたのためにどこまでやるかです。

予約語でファイルが壊れることはもうない

{"class": 1} は以前こう出ていました。

class Root(BaseModel):
    class: int

これは Python ではありません。ファイルは解析すらされません。予約語には下線が付き、Pydantic の別名が鍵を保ちます。

    class_: int = Field(alias="class")

本物の欠陥で、この文章を書く過程で見つけ、直しました。TypedDict の逃げ方は別です。属性名にできない鍵があると、定義全体が関数形式 Root = TypedDict('Root', {"class": int}) に切り替わります。そこでは鍵は文字列であり、何でも書けます。

標本があなたに言えないこと

| None は付かず、既定値も付きません。どの項目も必須です。標本がそれを持っていたからです。null は型 None になり、ほかを一切受け付けません。「文字列、ときどき null」なら str | None に直してください。無いこともあるなら = None も添えます。

同じ snake_case になる二つの鍵——fooBar と foo_bar——は、混ぜずに番号付きの接尾辞で分けます。どちらがどちらだったかは別名が記録します。

プライバシー

すべての処理はブラウザ内のJavaScriptだけで完結します。データがアップロードされることはないため、機密情報でも安心して利用でき、オフラインでも動作します。

よくある質問

三つの書き方のどれを選べばよいですか。
外から来るデータを境界で検証したいなら Pydantic です。すでに信頼できて、ただの入れ物でよいなら `dataclass` です。手元にある辞書に注釈を付けたいだけで、実行時の振る舞いを変えたくないなら `TypedDict` です。読み取る構造は同じで、違うのは支払う代償だけです。
なぜ鍵の名前が変わったのですか。元の鍵はどこへ行きましたか。
Python の属性は snake_case なので、`firstName` は `first_name` になります。Pydantic の書き方では `Field(alias="firstName")` が元の鍵を保ち、解析は変わらず働きます。`dataclass` に差し出せる別名はなく、名前だけが残ります。`TypedDict` は鍵をそのまま保ち、属性名にできない鍵があれば関数形式に切り替えます。
`class` や `def` という鍵はどうなりますか。
下線が付いて `class_`、`def_` になり、Pydantic では `Field(alias="class")` が添います。`class: int` を出していた頃は、Python が解析すらできないファイルになっていました。本物の欠陥で、この文章を書く過程で見つけ、直しました。`TypedDict` は `TypedDict('Root', {"class": int})` と書いて、その問いごと避けます。

関連ツール