PythonのJSON処理とは?

JSON(JavaScript Object Notation)は、軽量で可読性の高いデータ交換フォーマットで、広く使用されています。JSONは、シンプルなテキスト形式でデータを表現するため、API通信や設定ファイルの保存、データの交換に最適です。Pythonには、JSONデータを簡単に操作できるjsonモジュールが標準で搭載されています。 この記事では、Pythonjsonモジュールを使ってJSONデータを読み書きする方法や、Pythonオブジェクトとの相互変換について詳しく解説します。

JSONの基本構造

まず、JSONデータは以下のように、キーと値のペアからなる構造を持ちます。JSONの値には、文字列、数値、配列、オブジェクト(辞書)、ブール値、およびnullを使用できます。

{
  "name": "John",
  "age": 30,
  "is_student": false,
  "courses": ["Math", "Science"],
  "address": {
    "city": "New York",
    "zip_code": "10001"
  }
}

このJSONデータには、名前や年齢、学生かどうか、コースリスト、住所情報が含まれています。

Pythonのjsonモジュール

Pythonjsonモジュールでは、JSONデータをPythonオブジェクト(辞書やリストなど)に変換したり、その逆にPythonオブジェクトをJSON形式の文字列に変換したりすることができます。

主要な関数

  • json.loads(): JSON形式の文字列をPythonオブジェクトに変換
  • json.dumps(): PythonオブジェクトをJSON形式の文字列に変換
  • json.load(): JSONファイルをPythonオブジェクトに変換
  • json.dump(): PythonオブジェクトをJSON形式でファイルに書き込み

JSON文字列とPythonオブジェクトの変換

json.loads()でJSON文字列をPythonオブジェクトに変換

json.loads()を使うと、JSON形式の文字列をPythonの辞書やリストなどのオブジェクトに変換できます。

import json
# JSON形式の文字列
json_str = '{"name": "John", "age": 30, "is_student": false}'
# JSON文字列を`Python`の辞書に変換
data = json.loads(json_str)
print(data)  # 出力: {'name': 'John', 'age': 30, 'is_student': False}
print(type(data))  # 出力: <class 'dict'>

この例では、JSON文字列がPythonの辞書に変換されています。

json.dumps()PythonオブジェクトをJSON文字列に変換

逆に、json.dumps()を使ってPythonの辞書やリストをJSON形式の文字列に変換できます。

import json
# Pythonの辞書
data = {
    "name": "John",
    "age": 30,
    "is_student": False
}
# PythonオブジェクトをJSON文字列に変換
json_str = json.dumps(data)
print(json_str)  # 出力: {"name": "John", "age": 30, "is_student": false}

この例では、Pythonの辞書がJSON形式の文字列に変換されています。

JSONファイルの読み書き

Pythonjsonモジュールは、JSON形式のファイルを直接読み込んだり、Pythonオブジェクトをファイルに書き込むことも簡単にできます。

json.load()でJSONファイルを読み込む

JSONファイルを読み込んでPythonのオブジェクトに変換するには、json.load()を使います。

例: JSONファイルの読み込み

import json
# sample.json ファイルを読み込む
with open('sample.json', 'r') as file:
    data = json.load(file)
print(data)  # JSONファイルの内容が`Python`の辞書として出力される

この例では、sample.jsonファイルを開いてその内容を読み込み、Pythonの辞書として扱います。

json.dump()PythonオブジェクトをJSONファイルに書き込む

Pythonの辞書やリストをJSON形式でファイルに保存するには、json.dump()を使用します。

例: JSONファイルへの書き込み

import json
# 保存するデータ
data = {
    "name": "Alice",
    "age": 25,
    "is_student": True
}
# dataをoutput.jsonとして保存
with open('output.json', 'w') as file:
    json.dump(data, file)

この例では、data辞書をoutput.jsonファイルにJSON形式で保存しています。

JSONデータのフォーマット

インデントを指定して見やすくする

json.dumps()json.dump()には、インデントを指定するオプションがあります。これにより、出力されるJSONデータを整形して見やすくすることができます。

import json
data = {
    "name": "Alice",
    "age": 25,
    "is_student": True,
    "courses": ["Math", "Physics"]
}
# インデントを指定して整形
json_str = json.dumps(data, indent=4)
print(json_str)

このようにindent=4を指定すると、出力が次のようにインデントされた見やすい形式になります。

{
    "name": "Alice",
    "age": 25,
    "is_student": true,
    "courses": [
        "Math",
        "Physics"
    ]
}

ソートされた出力

json.dumps()では、キーをアルファベット順にソートして出力することも可能です。これはsort_keys=Trueオプションを指定することで実現できます。

json_str = json.dumps(data, indent=4, sort_keys=True)
print(json_str)

この設定を行うと、JSONオブジェクトのキーがソートされて出力されます。

カスタムオブジェクトのシリアライズとデシリアライズ

Pythonの標準的なデータ型(辞書、リスト、タプルなど)以外にも、独自に定義したクラスのインスタンスをJSON形式に変換する方法があります。

カスタムオブジェクトのシリアライズ

デフォルトでは、json.dumps()Pythonのカスタムクラスをシリアライズできません。default引数を使って、カスタムシリアライザを定義する必要があります。

例: カスタムクラスのJSON変換

import
 json
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
# カスタムオブジェクトを辞書に変換する関数
def person_to_dict(obj):
    if isinstance(obj, Person):
        return {"name": obj.name, "age": obj.age}
    raise TypeError(f"Type {type(obj)} not serializable")
# Personオブジェクトを作成
person = Person("John", 30)
# カスタム関数を使ってシリアライズ
json_str = json.dumps(person, default=person_to_dict)
print(json_str)  # 出力: {"name": "John", "age": 30}

このように、カスタムオブジェクトをシリアライズするためには、そのオブジェクトを辞書形式に変換する関数を定義し、default引数に指定します。

カスタムオブジェクトのデシリアライズ

逆に、JSON文字列をカスタムクラスにデシリアライズする場合は、object_hook引数を使います。

例: JSONからカスタムオブジェクトへの変換

import json
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
# 辞書からPersonオブジェクトを生成する関数
def dict_to_person(d):
    return Person(d['name'], d['age'])
# JSON文字列
json_str = '{"name": "John", "age": 30}'
# JSONをPersonオブジェクトに変換
person = json.loads(json_str, object_hook=dict_to_person)
print(person.name, person.age)  # 出力: John 30

この例では、object_hookを使用してJSONデータをPersonオブジェクトに変換しています。

例外処理

JSONの読み書き中にエラーが発生することがあります。例えば、不正なJSONフォーマットの場合にはJSONDecodeErrorが発生します。こういった場合、例外処理を取り入れることでエラーハンドリングができます。

import json
json_str = '{"name": "John", "age": "30"'  # 間違ったJSONフォーマット
try:
    data = json.loads(json_str)
except json.JSONDecodeError as e:
    print(f"JSONデコードエラー: {e}")

結論

Pythonjsonモジュールを使えば、JSON形式のデータを簡単に読み書きしたり、Pythonのオブジェクトに変換して操作できます。データのやり取りや保存が必要な場面では、JSONが非常に便利であり、APIとの通信や設定ファイルの管理などに多く使われています。jsonモジュールの基本的な使い方から応用的なカスタムオブジェクトの処理まで理解しておくことで、より柔軟なデータ処理が可能になります。