- JSON は Python のコア型にきれいにマッピングされ、オブジェクトと配列は辞書とリストとして表現されるため、データ交換が簡単になります。
- Python の json モジュールは、きれいな印刷、カスタム エンコーダー、安定したキー順序付けのオプションを備えた柔軟なダンプ/ロード機能を提供します。
- ファイルと API からのネストされた JSON の読み取り、書き込み、解析は、同じコア ツールと慎重なエラー処理に依存します。
- 基本的なシリアル化に加えて、Python の JSON は、フォーマット、検証、CSV や XML などの他のデータ形式との統合をサポートします。

JSONは静かにウェブ上のデータのデフォルト言語になりました。 Pythonを書いていると、API、設定ファイル、サイドプロジェクト用の小さな「データベース」、ログ、テストフィクスチャなど、あらゆるところでJSONに遭遇します。Pythonのデータ型がJSONにどのようにマッピングされるか、そして json モジュールが本当に機能するのは、日常の多くのタスクを突然簡単にするスキルの 1 つです。
このガイドでは、Pythonプログラマーの観点からJSONを解説します。 JSONとは何か、JavaScriptとどのように関係しているか、どのPython型を表現できるか、そしてJSONを解析、生成、整形、検証、カスタマイズする方法を説明します。 jsonまた、ファイルやAPIの操作などの実際のユースケース、ネストされたデータの処理方法、エラーや次のような特殊な値などのエッジケースについても見ていきます。 NaN そして無限。
JSONとは何か、そしてPythonデータとどのように関係するのか
JSONはJavaScript Object Notationの略で、構造化データ用のテキスト形式です。 元々はJavaScriptのオブジェクトと配列から構文を借用したものです。JavaScriptにルーツを持つにもかかわらず、JSONは言語に依存せず、Pythonを含むほぼすべての現代言語でサポートされているため、サービス、クライアント、サーバー間のデータ交換に最適です。
概念的には、JSON は次の 2 つの複合ビルディング ブロックのみを使用します。 JavaScript オブジェクト そしてJavaScript 配列オブジェクトはPythonの辞書のように振る舞い、配列はPythonのリストのように振る舞います。これら2つと、いくつかのプリミティブ型を組み合わせることで、JSONは複雑にネストされたデータ構造を記述できます。
JavaScript (および JSON) のオブジェクトは次のようになります。 {"key1": value1, "key2": value2}これはキーと値のペアのコレクションで、キーは文字列、値は有効なJSON値(他のオブジェクトや配列を含む)です。これはPythonの dict.
JavaScript (および JSON) の配列は Python のリストに似ています。 これは、有効なJSON型を使用した順序付き値のコレクションです。オブジェクトと配列を任意にネストすることで、ユーザープロファイル、設定ツリー、APIレスポンスなどのリッチデータをモデル化できます。
JSON型とPython型のマッピングは非常に簡単です。 そのため、冗談めかして「PYON」(Python Object Notation)と呼ばれることもあります。PythonでJSONをエンコードまたはデコードする場合、以下の対応関係が適用されます。
- JSONオブジェクト → Python
dict - JSON配列 → Python
list - JSON文字列 → Python
str - JSON数値(整数)→ Python
int - JSON数値(実数)→ Python
float - JSONの
true→ PythonTrue - JSONの
false→ PythonFalse - JSONの
null→ PythonNone
重要な制限の1つは、JSONオブジェクトのキーは常に文字列であるということです。 Pythonでエンコードすると dict 文字列以外のキー(整数やタプルなど)の場合、設定に応じてキーは文字列に変換されるかエラーが発生します。JSONは設定やレコードなどの構造化データの保存に最適ですが、 任意の Python オブジェクトに対する一般的な pickling メカニズム。

Pythonの組み込みjsonモジュール
Pythonには、以下の標準ライブラリモジュールが付属しています。 json, 文字列の解析、ファイルからの読み込み、Pythonオブジェクトのシリアル化、データのエンコードとデコード方法のカスタマイズなど、JSONを扱うために必要なすべての機能を提供します。一般的なJSONタスクでは、外部依存は一切不要です。
最も頻繁に使用する 4 つのコア機能は次のとおりです。 json.dumps() および json.dump() PythonオブジェクトをJSONに変換するため、そして json.loads() および json.load() JSONからPython型に戻すためのものです。「s」バージョンは文字列で動作し、「s」なしバージョンはファイルのようなオブジェクトで動作します。
当学校区の json エンコーダはデフォルトで特定のPython型セットをサポートしています。 すなわち dict, list, tuple (配列として)、 str、数字(int, float、整数/浮動小数点派生列挙型)と3つの特別なシングルトン True, False, Noneこれらは、前述のマッピングに従って、同等の JSON に変換されます。
カスタムオブジェクトやデータ型をシリアル化する必要がある場合は、 モジュールの設計は拡張可能です。JSONエンコーダをサブクラス化して、 default() メソッド、またはカスタム default 機能に json.dump() / json.dumps()このカスタムフックはJSONシリアル化可能なもの( dict or list)、または上げる TypeError 指定されたオブジェクトの処理方法がわからない場合。
内部的には、モジュールは次のようなメソッドも提供しています。 encode() および iterencode(), PythonデータをJSON文字列に変換する。 iterencode() エンコードされた部分を段階的に生成します。これらのメソッドは直接使用されることはあまりありませんが、非常に大きなJSONレスポンスをストリーミングする必要がある場合は知っておく価値があります。
Python オブジェクトを JSON に変換する
PythonデータをJSONテキストに変換するには、 json.dump() or json.dumps(), ファイルに直接書き込むか、メモリ内のJSON文字列を取得するかによって異なります。どちらの関数も、変換の動作を制御するための同じコアパラメータを共有しています。
関数 json.dump(obj, fp, ...) Pythonオブジェクトとファイルのようなオブジェクトを受け取り、 そしてJSON表現を書き出す obj そのファイルへの。メモリ内の対応するものは、 json.dumps(obj, ...)は、ファイルに書き込む代わりにJSON文字列を返します。どちらも次のような一連のキーワード引数を受け取ります。 skipkeys, ensure_ascii, check_circular, allow_nan, indent, separators, default, sort_keys.
これらの各オプションは、実際のプロジェクトで非常に重要な方法でエンコード動作を微調整します。 無効なキーをスキップするか、ASCII 出力を強制するか、結果を整形して出力するか、空白を制御するか、非標準オブジェクトのカスタムシリアル化を定義するか、テストや差分のためにキーの順序を安定させるかを選択できます。
主なパラメータの実際の意味は次のとおりです。
skipkeys: に設定されている場合True、辞書のキーが型str,int,float,boolorNone発生させる代わりに、黙ってスキップされますTypeErrorキーがおかしいときにフェイルファースト動作をしたい場合は、False.ensure_ascii: を特定いたします。True(デフォルト)、非ASCII文字および印刷できない文字はエスケープされます(例:\uXXXX)なので、出力は純粋なASCIIのままです。FalseUnicode 文字はそのまま書き込まれるため、通常は人間が読める構成やログに適しています。check_circular: ifTrueに設定すると、エンコーダーはリスト、辞書、カスタムエンコードされたオブジェクト内の循環参照をチェックし、無限再帰を防止します。Falseその安全網を無効にし、RecursionError構造が自己参照的である場合。allow_nan: ifTrue、特殊な浮動小数点値NaN,Infinity,-Infinity仕様上は厳密に有効なJSONではないものの、JavaScript互換の方法でエンコードされ、許可されています。Falseこのような値をエンコードしようとすると、ValueError.indent: 整形表示を制御する非負の整数(または文字列)。正の数値は、ネストされたレベルごとにスペースの数を表します。文字列("\t") はインデントに直接使用されます。None(デフォルト) 必要以上の改行を入れずに、最もコンパクトな表現を選択します。separators: タプル(item_separator, key_separator)項目間およびキーと値間の句読点と空白文字を制御します。最も厳密なJSONには通常、(",", ":")すべてのオプションのスペースを削除します。default: エンコーダが処理方法を知らないオブジェクトを受け取る関数。JSONでシリアライズ可能な代替値(dictorlist)、または上げるTypeErrorこれは、独自のクラスをシリアル化可能にするための主要なフックです。sort_keys: ifTrue辞書はキーがソートされた状態でエンコードされます。これは、JSONダンプを複数回実行しても安定した状態に保ちたい回帰テストや再現可能な出力に非常に便利です。
具体的な例として、Pythonの混合リストがあると想像してください。 整数と、名前、ID、浮動小数点スコアを含む辞書が含まれます。JSONは次のように作成して保存できます。
import pathlib
import json
path = pathlib.Path("myTextFile.json")
data =
with path.open(mode="wt") as f:
json.dump(data, f)
print(json.dumps(data, indent=4))
印刷されたJSONは、以下の方法できれいにフォーマットされます。 indent=4, 各リスト項目と辞書キーをそれぞれ1行に表示します。これにより、1行の密集したテキストに比べて、デバッグや手動編集がはるかに容易になります。
JSON を Python に解析する
JSONテキストからPythonオブジェクトに戻すには、 対応する関数のペアを使用します。 json.load() (ファイルのようなオブジェクトの場合)および json.loads() (JSON文字列の場合)。これらの関数は入力を解析し、以前と同じマッピングテーブルに従ってPython型を再作成します。
署名はおおよそ次のようになります。 json.load(fp, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, kw) および json.loads(s, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, kw)基本レベルでは、JSON 入力だけで呼び出すことができますが、追加の引数を使用すると、より高度な解析動作が可能になります。
フックのような object_hook および object_pairs_hook JSONオブジェクトをPython構造に変換する方法をカスタマイズできます。 解読された dict またはリスト (key, value) それぞれペアです。これは、JSONから直接カスタムクラスを構築したり、特定の方法で順序を維持したりする場合に役立ちます。
その他の呼び出し可能オブジェクトとしては parse_float, parse_int, parse_constant 数値や特殊トークンの解釈方法を制御できます。例えば、 Decimal float 金銭的価値に変換したり "NaN", "inf", "-inf" 選択したセンチネル オブジェクトに変換します。
前の例を続けると、次のように記述した JSON ファイルを読み取ることができます。
with path.open(mode="rt") as f:
data = json.load(f)
print(data)
結果の出力は通常のPythonリストと辞書になります。 例えば 通常のPython操作で操作できます。コードの観点から見ると、これは再び「単なるデータ」になります。
PythonでJSONに変換できる型
すべてのPythonオブジェクトをすぐにJSONに変換できるわけではない。 許容されるセットを覚えておくと便利です。実用的なエンコーダは、一般的なコンテナ型とスカラー型に加えて、ブール値と None、そしてそれらを JSON 型の最小限のセットにマッピングします。
デフォルトでは、以下のPythonオブジェクトを安全に渡すことができます。 json.dumps():
dict(JSONオブジェクトとしてエンコード)listおよびtuple(JSON配列としてエンコード)str(JSON文字列としてエンコード)intおよびfloat(JSON数値としてエンコード)TrueおよびFalse(エンコードするとtrueおよびfalse)None(エンコードするとnull)
Pythonでこれらをエンコードすると、JSONへのマッピングは簡単です。 デコード時にも同様です。例えば、Python tuple JSON配列になり、 list ロード時に復帰。 int or float 数字としてエンコードすることもできます。
その他すべてはカスタムが必要です default ハンドラ (オブジェクトをシリアル化可能な表現に変換する)または TypeErrorこれは設計によるものです。JSONはデータ用であり、任意のオブジェクトグラフをシリアライズするためのものではなく、 pickle.
日常業務のほとんどにおいて、このタイプのサブセットはほとんどのユースケースをカバーします。 API ペイロード、構成ツリー、ユーザー設定、基本ログ、プロトタイプまたはシングルユーザー ツール用の小さな「データベースのような」ファイルなどが含まれます。
きれいな印刷、コンパクトな出力、そして順序付けられたキー
生のJSON出力は完全に有効ですが、読みにくい傾向があります。 不要な空白文字が含まれずに生成されることが多いためです。デバッグ、ログ記録、または他の開発者との共有などでは、ワンライナーではなく、読みやすくインデントされたJSON形式が求められることがよくあります。
当学校区の indent のパラメータ json.dumps() 美しい印刷の主な手段である Pythonにインデントレベルごとに何個のスペース(またはどの文字列)を使用するかを指定することができます。典型的な選択肢は indent=4ただし、一部のコードベースでは 2 つのスペースまたはタブ文字が好まれます。スタイルの規則はプロジェクトによって異なります。
当学校区の separators 引数を使用すると、空白をさらに微調整できます。 次のようなタプルを与える (", ", ": ") 人間に分かりやすい出力のために、デフォルトで が設定されます。ネットワーク上のペイロードサイズを削減するなど、可能な限りコンパクトな表現が必要な場合は、 separators=(",", ":") カンマとコロンの後のスペースを削除します。
ユニットテストやスナップショットの比較など、決定論的な出力を重視する場合は、 活性化する sort_keys=True エンコーダーは辞書のキーをソートされた順序で出力します。これにより、辞書がキーを異なる順序で出力したという理由だけで、意味的に同一のデータを生成する2回の実行結果に差異が生じることはありません。
一緒に、 indent, separators, sort_keys 多くのコントロールを与える JSON がマシン向けに最適化されているか (コンパクト、空白なし)、人間向けに最適化されているか (インデントされ、整列され、実行時に安定した形状) によって異なります。
ネストされたデータ、解析戦略、アクセスパターン
実際の JSON では、フラット構造は例外です。 通常、ネストされたオブジェクトや配列を扱うことになります。eコマースアプリケーションの典型的なユーザーレコードを考えてみましょう。個人情報、ネストされた配送先住所、ネストされた請求情報、そしておそらく注文リストなど、それぞれが複雑な構造になっています。
JSONをPythonにデコードすると、ネストされたデータは辞書とリストの組み合わせになります。 標準的なインデックスとキー検索を使ってアクセスできます。浅い構造の場合、これは簡単です。 data, data、などなど。
深くネストされた構造や動的な構造の場合は、より一般的なアプローチが適しているかもしれません。 例えば、キーを検索したり、辞書やリストのツリーを巡回したりする小さな再帰関数を書くなどです。任意にネストされたデータを走査する場合、再帰的なソリューションは反復的なソリューションよりも短く読みやすいことがよくあります。
ネストされていない(フラットな)JSONは、ハードコードされたキーで直接アクセスするのが簡単です。 これは、小規模なユーティリティや入力を完全に制御できる場合には十分です。しかし、外部APIを利用する場合は、構造をカプセル化する小さなヘルパー関数を書くのが一般的です。 コードベース全体にチェーンします。
深さに関係なく、同じ json.loads() 適用される動作: この関数はJSON文字列を受け取り、通常のPythonツールで操作できるネイティブPython型を生成します。通常のPythonツール以外、特別な構文は必要ありません。 dict および list 索引付け。
JSONファイルの操作:読み取り、書き込み、追加
JSONは驚くほど便利な軽量ストレージフォーマットです 小規模なプロジェクト、設定ファイル、あるいは永続的な状態を保持する必要があるスクリプトなどに適しています。完全なデータベースに直接アクセスする代わりに、1つか2つのJSONファイルでかなり長い間対応できる場合が多いです。
JSON をファイルに書き込むには、通常、次の 2 つの手順が必要です。 Pythonデータをシリアル化する json.dumps() または直接 json.dump()を実行し、結果の文字列がディスクに書き込まれることを確認します。 open('data.json', 'w')、書き込みモードでファイル ハンドルを取得し、ファイルを作成するか、既に存在する場合はファイルを切り捨てます。
ネストされた構造の場合、プロトコルはフラット データと変わりません。 あなたはまだ同じものを使っています json.dump() 呼び出しによって、リストと辞書のネストされた組み合わせが再帰的にエンコードされます。通常、必要なのは、読みやすさとファイルサイズを考慮して、どの程度のインデントを設定するかだけです。
ファイルからJSONを読み込む場合は逆の手順になります。ファイルをテキストモードで開き、 ファイルオブジェクトを渡す json.load()と入力すると、Pythonのデータ構造が返されます。繰り返しますが、動作はネストの深さとは無関係です。デコーダーがすべてを自動的に処理します。
既存のファイルにJSONデータを追加する必要がある場合は、 状況はより複雑になります。JSON自体は、ファイル全体が有効なJSONである必要があるため、「ストリーミング追加」を単純な方法ではサポートしていません。一般的なパターンとしては、レコードの配列を保存し、配列全体を読み取り/変更/書き込みするか、行区切りのJSON(各行が独立したJSONオブジェクトであり、前の行を書き換えることなく追加できる)を使用する方法があります。
現実世界における JSON: API、ストレージ、そして交換
実際のアプリケーションの構築を始めると、JSONはすぐに接着剤になります Webクライアントとサーバー、マイクロサービス、サードパーティAPIを接続するフレームワークです。コンパクトでありながら、人間が容易に読み書きできるという点が評価されています。
APIインタラクションでは、JSONが最も一般的なペイロード形式です。 特にRESTfulサービスでは、Pythonアプリケーションは通常次のようなライブラリを使用します。 requests HTTPリクエストを送信し、 JSONレスポンスを受信するそれらの応答を解析し、 json.loads() またはそれをラップするヘルパー メソッドを使用します。
JSONは設定ファイルやログの一般的なフォーマットでもあります。 構造化されたキーバリュー型の性質により、プレーンテキストよりもはるかに表現力に優れながら、完全なデータベースに比べてシンプルさを維持できます。システムコンポーネントはJSON経由で設定を共有でき、ログアグリゲータはJSONログを解析して、より簡単にフィルタリングや分析を行うことができます。
もう一つの大きなユースケースは、データ構造のシリアル化とデシリアル化です。 メモリ内のコレクションをJSON文字列に変換し(シリアル化)、その後再構築する(デシリアル化)。このようにしてユーザー設定を保存します。 構造化されたメッセージを送信する JSON 互換型に従うかカスタム エンコーダーを提供する限り、キューを介して送信したり、ネストされたオブジェクトをサービス境界を越えて送信したりできます。
JSONだけでなく、PythonコードではJSONと他の形式の間で変換する必要があることがよくあります。 XML、CSV、プレーンテキストなどです。例えば、レガシーシステムからCSVを読み取り、それを辞書のリストに変換し、最新のAPI用にJSONとしてダンプすることができます。あるいは、APIからJSONを取得し、正規化してCSVを作成し、アナリストがスプレッドシートにロードできるようにすることも可能です。
JSONのフォーマット、検証、その他の操作
基本的な読み書きに慣れたら、 読みやすくするためのフォーマット、ネストされた構造のフラット化、文字列が実際に JSON であることの検証、一貫性のある比較のためのデータの並べ替えなど、ワークフローを改善するために JSON データに対して実行できる小さいながらも便利な操作が多数あります。
プリティープリント json.dumps(..., indent=...) 最初のステップです。 階層構造が適切に配置され、構造上の問題点を一目で把握しやすくなります。これは、デバッグ時やドキュメント内で例を共有する場合に特に役立ちます。
ネストされたJSONをフラット化することで、下流の処理と分析が容易になります。 特に、データをCSVのような表形式に変換したり、深くネストされたオブジェクトではなくキーと値のペアを想定するツールにデータを入力したりする必要がある場合は、フラット化が重要になります。通常、フラット化は、辞書やリストの再帰や反復的な走査を用いて、自分で実装します。
JSONの検証は、多くの場合、それを解析して例外をキャッチすることに行き着きます。 特に文字列の構文が正しいかどうかだけを検証する場合は、より厳密なチェックを行うにはJSONスキーマや外部ライブラリを使うこともできますが、多くの場合、単純な try/except 周りに json.loads() 十分です
JSONデータを特定の値やキーでソートすると、レスポンスを比較するときに役立ちます。 テスト用の安定したスナップショットを生成したり、類似のオブジェクトがグループ化されているかを確認したりするために使用します。ダンプする前にPythonのリストと辞書をソートするか、 sort_keys=True オブジェクト内のキーの順序に重点が置かれている場合。
JSON を扱う際のエラー処理
適切に構造化されたシステムでも、不正なJSONや予期しないデータに遭遇する可能性があります。 JSONの解析とエンコードに関する堅牢なエラー処理が不可欠です。Pythonではこれらの問題を例外で表現しており、それらに対処する慣用的な方法は、操作を例外でラップすることです。 try...except ブロック。
JSONをデコードする場合、最も一般的な問題は無効な構文です。 プロパティ名を囲む引用符が抜けていたり、末尾にコンマが付いていないなど。 json モジュールはデコードエラーを発生させます(通常は json.JSONDecodeError) をキャッチしてログに記録したり、ユーザーフレンドリーなメッセージに変換したりできます。
たとえば、壊れた文字列を解析しようとすると、次のようなエラーが発生する可能性があります。 Failed to decode JSON: Expecting property name enclosed in double quotes: line 1 column 29 (char 28)この種のメッセージは、解析が失敗したことだけでなく、入力のどこでパーサーが混乱したかを伝えます。
エンコード側では、 TypeError サポートされていない型をシリアル化しようとすると、 or ValueError 許可しない場合 NaN そして無限大 allow_nan=False しかし、データにはそのような値が含まれています。コンテナ内の循環参照も原因となる可能性があります。 RecursionError 循環チェックを無効にする場合。
ベストプラクティスはJSON操作を誤りのあるI/Oとして扱うことです。 特にネットワークソースや外部ファイルから読み込む場合は、常に何か問題が発生する可能性を想定し、それに応じて例外をキャッチし、データにさらに具体的な制約を課す検証レイヤーを追加するなどしてください。ラッピング json.loads() またはAPIヘルパーメソッド try...except ブロックはコードの残りの部分を連鎖的な障害から保護し、 ユーザーフレンドリーなJSONエラー 適切な場合にはクライアントに提供します。
Python の Web API で JSON を使用する
Pythonから通信するほとんどのWeb APIはJSONを送受信します。 典型的な開発スタックは、 requests ライブラリ(HTTP用) json モジュール(JSONの解析と生成用)。この組み合わせにより、API統合が非常に自然になります。
一般的なパターンはAPIエンドポイントを呼び出すことです。 応答ステータスコードが成功を示していることを確認し、 JSON本体を解析するそこから、フィールドにアクセスし、ネストされたデータを処理して、応答を独自のドメイン モデルまたはビュー オブジェクトにマップできます。
ネットワーク呼び出しが関係する場合、エラー処理は特に重要になります。 無効なJSONだけでなく、タイムアウト、接続エラー、JSONではなくHTMLで応答するサーバー側の障害が発生する可能性があるためです。ラッピング json.loads() またはAPIヘルパーメソッド try...except ブロックは、コードの残りの部分を連鎖的な障害から保護します。
一度解析されると、API JSONは他のPythonデータ構造と同じように動作します。 そのため、これまでに説明したすべてのテクニック(整形出力、フラット化、検証、ソート)が直接適用されます。PythonデータとJSON間のやり取りに慣れることは、サービス同士を接続する際に生産性を大幅に向上させます。 実際のアプリケーションの構築早い段階で JSON 処理パターンに注意を払うと、後でデバッグにかかる時間を節約できます。
Python における JSON は、単一の関数呼び出しというよりはツールボックスに近いものです。 明確な型マッピング、柔軟なエンコード パラメータ、カスタム型用のフック、シンプルだが強力なファイル I/O、外部からのデータを解析、フォーマット、検証するための堅牢なパターンなど、JSON は最新のデータ駆動型アプリケーションを扱う Python プログラマーにとって自然な選択肢となっています。