Python JSON:エンコード、デコード、ファイル処理の実践ガイド
Python JSON:エンコード、デコード、ファイル処理の実践ガイド
PythonにおけるJSONとは?
JSON(JavaScript Object Notation)は最も広く使われるテキストベースのデータ交換フォーマットです。Pythonではネイティブデータ構造に直接マッピング:オブジェクトはdict、配列はlist、文字列、数値、ブール値、nullはそれぞれstr、int/float、bool、Noneに対応。標準ライブラリのjsonモジュールがすべての変換を処理します。
PythonのJSONライブラリ
スクリプトで一度インポート:
import json
モジュールは4つのコアメソッドを提供:
| メソッド | 説明 |
|---|---|
| dumps() | PythonオブジェクトをJSON文字列に変換 |
| dump() | JSON文字列をファイルオブジェクトに直接書き込み |
| loads() | JSON文字列をPythonオブジェクトにパース |
| load() | JSONファイルを読み取りPythonオブジェクトにパース |
PythonからJSONへ(エンコード)
エンコードはPythonデータ型をJSONに変換するプロセス。デフォルトマッピングは以下:
| Python | JSON |
|---|---|
| dict | Object |
| list | Array |
| str | String |
| int | Number (int) |
| float | Number (real) |
| True | true |
| False | false |
| None | null |
json.dumps()使用例:
import json
x = {
"name": "Ken",
"age": 45,
"married": True,
"children": ("Alice", "Bob"),
"pets": ["Dog"],
"cars": [
{"model": "Audi A1", "mpg": 15.1},
{"model": "Zeep Compass", "mpg": 18.1}
]
}
# キーをソートしてプリティプリント
sorted_string = json.dumps(x, indent=4, sort_keys=True)
print(sorted_string)
出力:
{
"age": 45,
"cars": [
{ "model": "Audi A1", "mpg": 15.1 },
{ "model": "Zeep Compass", "mpg": 18.1 }
],
"children": [ "Alice", "Bob" ],
"married": true,
"name": "Ken",
"pets": [ "Dog" ]
}
JSONオブジェクトをファイルに書き込みはjson.dump()で簡単:
with open('json_file.json', 'w') as file_write:
json.dump(x, file_write, indent=4, sort_keys=True)
スクリプト実行後、json_file.jsonにシリアライズされたデータが含まれます。
JSONからPythonへ(デコード)
デコードは逆変換で、JSON文字列やファイルをネイティブPythonオブジェクトに戻します。変換テーブルはエンコードの鏡像:
| JSON | Python |
|---|---|
| Object | dict |
| Array | list |
| String | str |
| Number (int) | int |
| Number (real) | float |
| true | True |
| false | False |
| null | None |
json.loads()使用例:
import json
person_data = '{"person": {"name": "Kenn", "sex": "male", "age": 28}}'
obj = json.loads(person_data)
print(obj)
print(type(obj))
print(obj.get('person'))
出力:
{'person': {'name': 'Kenn', 'sex': 'male', 'age': 28}}
<class 'dict'>
{'name': 'Kenn', 'sex': 'male', 'age': 28}
JSONファイルを直接読み取り:
with open('json_file.json') as f:
data = json.load(f)
print(data)
出力:
{'name': 'Ken', 'age': 45, ...}
コンパクトとプリティプリントエンコード
ネットワーク送信用にコンパクトエンコードで空白除去:
lst = ['a', 'b', 'c', {"4": 5, "6": 7}]
compact = json.dumps(lst, separators=(',', ':'))
print(compact)
出力:
["a","b","c",{"4":5,"6":7}]
人間可読用にプリティプリントでインデント:
dic = {"a": 4, "b": 5}
pretty = json.dumps(dic, indent=4, separators=(',', ': '))
print(pretty)
出力:
{
"a": 4,
"b": 5
}
複雑なオブジェクトのエンコード
jsonモジュールは任意のオブジェクトをシリアライズできません。complex数を扱うにはdefault関数を指定:
def complex_encode(o):
if isinstance(o, complex):
return [o.real, o.imag]
raise TypeError(f"{repr(o)} is not JSON serializable")
print(json.dumps(4 + 5j, default=complex_encode))
出力:
[4.0, 5.0]
複雑なオブジェクトのデコード
object_hookでカスタムマーカーを検出し複素数を再構築:
def is_complex(obj):
if "__complex__" in obj:
return complex(obj["real"], obj["img"])
return obj
complex_obj = json.loads('{"__complex__": true, "real": 4, "img": 5}', object_hook=is_complex)
print(complex_obj)
出力:
(4+5j)
シリアライゼーション/デシリアライゼーション クラス
JSONEncoderとJSONDecoderクラスで細かな制御:
JSONEncoder.default(o)– カスタムオブジェクトのシリアライズ用にオーバーライドJSONEncoder.encode(o)– JSON文字列を返すJSONEncoder.iterencode(o)– 出力文字列をイテレーションJSONDecoder.decode(s)– JSON文字列をパースJSONDecoder.raw_decode(s)– 指定インデックスからパース
例:
from json.encoder import JSONEncoder
print(JSONEncoder().encode({"colour": ["red", "yellow", "green"]}))
URLからJSON取得
requestsでライブJSONフィードをダウンロード(例: CityBike NYC):
import json, requests
response = requests.get("https://feeds.citibikenyc.com/stations/stations.json")
bike_dict = json.loads(response.text)
print(bike_dict['stationBeanList'][0])
出力:
{'id': 487, 'stationName': 'E 20 St & FDR Drive', 'availableDocks': 24, ...}
JSON例外のハンドリング
主な例外はjson.JSONDecodeErrorで、ValueErrorのサブクラス。ハンドリング例:
try:
with open('bad.json') as f:
data = json.load(f)
except json.JSONDecodeError as e:
print(f"不正なJSON: {e}")
特殊な数値
RFC 8259ではInfinityやNaNは許可されていませんが、Pythonエンコーダは文字列として表現:
print(json.dumps(float('inf')))
print(json.dumps(float('nan')))
出力:
Infinity NaN
JSONでの重複キー
キーが複数回出現する場合、Pythonのjson.loads()は最後の出現のみを保持:
json.loads('{"a": 1, "a": 2, "a": 3}') # -> {'a': 3}
コマンドラインツール
json.toolモジュールでコマンドラインからJSONフォーマットと検証:
$ echo '{"name": "Kings Arthur"}' | python3 -m json.tool
{
"name": "Kings Arthur"
}
PythonでのJSONの利点
jsonモジュールによるネイティブサポート- プリティプリントで人間可読
- API、設定、データストレージで広く採用
- 言語非依存で軽量
制限事項
- カスタムエンコーダなしではカスタムデータ型非サポート
- 最大再帰深度で深くネストした構造に制限
- 大規模ドキュメントは完全読み込みでメモリ集約的になる可能性
Python JSONチートシート
| 関数 | 説明 |
|---|---|
| json.dumps(obj) | PythonオブジェクトをJSON文字列にシリアライズ |
| json.dump(obj, file) | JSON文字列をファイルに書き込み |
| json.dumps(obj, separators=(",", ":")) | スペースなしのコンパクト表現 |
| json.dumps(obj, indent=4) | インデント付きプリティプリントJSON |
| json.dumps(obj, sort_keys=True) | 辞書キーをアルファベット順ソート |
| json.dumps(obj, default=custom) | 非サポートオブジェクトをエンコード |
| JSONEncoder().encode(obj) | エンコーダクラス経由の手動シリアライズ |
| json.loads(s) | JSON文字列をPythonオブジェクトにパース |
| json.loads(s, object_hook=custom) | カスタムデシリアライズロジック |
| JSONDecoder().decode(s) | デコーダクラス経由の手動デシリアライズ |
Python
- Python データ型マスター: 実践ガイド
- Python 演算子完全マスター: 包括的ガイド
- Python whileループ完全マスター: 構文・例・ベストプラクティス
- Python pass文完全マスター: 実践ガイド
- Python 関数完全マスター: 構文・種類・実践例
- Python 関数引数完全マスター: 位置引数・キーワード引数・デフォルト引数
- Python辞書完全ガイド:作成、操作、高度なテクニック
- PythonファイルI/O:ファイル操作、読み書き、管理のマスター
- Pythonでファイル・ディレクトリの存在確認:実践ガイド
- PythonファイルI/O:入出力操作をマスターする
- Java BufferedReader でファイル読み込み:実践ガイドと例