🦔
PythonでJSONを扱いたい時に見る記事
PythonでJSONを扱う時、違うメソッドを使用してエラーが出たり、引数の設定について毎回調べていたため備忘録も兼ねて記事にしました。
参考
バージョン
- Python 3.10.14
概要
以下のテーブルは、本記事で扱う4つの主要なメソッドの概要を示しています。
メソッド | 説明 | 入力 | 出力 |
---|---|---|---|
json.dump() |
PythonオブジェクトをファイルにJSON形式で書き込む | Pythonオブジェクト&fp(ファイルポインタ) | なし(ファイルに書き込み) |
json.dumps() |
PythonオブジェクトをJSON形式の文字列に変換する | Pythonオブジェクト | JSON文字列 |
json.load() |
JSONファイルからPythonオブジェクトを読み込む | fp(ファイルポインタ) | Pythonオブジェクト |
json.loads() |
JSON形式の文字列をPythonオブジェクトに変換する | JSON文字列 | Pythonオブジェクト |
dump
,dumps
PythonオブジェクトからJSONへの変換は
json.dump()
: オブジェクトをJSONファイルに書き込む
Pythonのオブジェクトをファイルに(JSON形式で)書き込むための関数です。オブジェクトをJSON形式のfpへのストリームとして変換します。
- 関数の定義
def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
default=None, sort_keys=False, **kw):
- 使い方
main.py
import json
# サンプルデータを作成
data = {
"名前": "山田太郎",
"年齢": 30,
}
# JSONファイルに書き込む
with open('data.json', 'w', encoding='utf-8') as fp:
json.dump(data, fp, ensure_ascii=False, indent=4)
- 出力結果(jsonファイル)
data.json
{
"名前": "山田太郎",
"年齢": 30
}
※fp
はfile pointer
の略で、データを書き込めるもの全般を指しています。例えば、open()
関数でファイルを開くと、ファイルオブジェクトが返され、そのオブジェクトが「fp」と呼ばれることがあります。また、StringIO
やBytesIO
もfp
として扱われます。
ここで扱うことができるfpは.write()
がサポートされているものを指します。
引数で設定できる値
引数 | デフォルト値 | 説明 |
---|---|---|
obj |
- | JSONに変換したいPythonオブジェクト。辞書、リスト、文字列、数値などが対象。 |
fp |
- | "file pointer"の略。.write() メソッドを持つファイルライクなオブジェクト。通常はopen() で開いたファイルオブジェクトを指定。 |
skipkeys |
False |
True にすると、辞書のキーが文字列や数値以外の場合、エラーを出さずにスキップする。 |
ensure_ascii |
True |
True だと、非ASCII文字をエスケープする。False なら、そのまま出力する。 |
check_circular |
True |
循環参照をチェックするかどうか。False にすると高速化するが、循環参照があるとエラーになる。 |
allow_nan |
True |
True なら、非数(NaN)や無限大(Infinity)をJavaScriptの表現で出力する。False だとエラーになる。 |
indent |
None |
インデントのレベルを指定。None だとインデント無し、数字ならそのスペース数、文字列ならその文字でインデントする。 |
separators |
- | 項目と項目の区切り文字、キーと値の区切り文字をタプルで指定する。 |
default |
- | JSONに直接変換できないオブジェクトを変換するための関数を指定する。 |
sort_keys |
False |
True にすると、辞書のキーをソートして出力する。 |
cls |
- |
JSONEncoder のサブクラスを指定して、エンコードの挙動をカスタマイズできる。 |
json.dumps()
: オブジェクトをJSON形式の文字列に変換
json.dumps()
はPythonのオブジェクトをJSON形式の文字列に変換する関数です。
- 関数の定義
def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
default=None, sort_keys=False, **kw):
- 使い方
main.py
import json
# サンプルデータを作成
data = {
"名前": "山田太郎",
"年齢": 30,
}
# JSON文字列を作成
json_str = json.dumps(data, ensure_ascii=False, indent=4)
print(json_str)
- 出力結果
{
"名前": "山田太郎",
"年齢": 30
}
引数で設定できる値
json.dump()
とほぼ同じため省略。
load
,loads
JSONからPythonオブジェクトへの変換は
json.load()
: JSONファイルからPythonオブジェクトを読み込む
json.load()
はJSONファイルからデータを読み込み、Pythonオブジェクトに変換する関数です。
- 関数の定義
def load(fp, *, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
- 使い方
main.py
import json
# JSONファイルから読み込む
with open('data.json', 'r', encoding='utf-8') as fp:
data = json.load(fp)
print(data)
print(type(data))
- 入力ファイル(JSONファイル)
data.json
{
"名前": "山田太郎",
"年齢": 30
}
- 出力結果
{'名前': '山田太郎', '年齢': 30}
<class 'dict'>
引数で設定できる値
引数 | デフォルト値 | 説明 |
---|---|---|
fp |
- | JSONデータを含むファイルオブジェクト。.read() メソッドをサポートしている必要がある。 |
cls |
None |
JSONDecoder のサブクラスを指定して、デコードの挙動をカスタマイズできる。 |
object_hook |
None |
デコードされた辞書に対して呼び出される関数。戻り値が辞書の代わりに使用される。 |
parse_float |
None |
JSONの浮動小数点数をデコードする際に使用する関数。デフォルトはfloat() 。 |
parse_int |
None |
JSONの整数をデコードする際に使用する関数。デフォルトはint() 。 |
parse_constant |
None |
-Infinity , Infinity , NaN をデコードする際に使用する関数。 |
object_pairs_hook |
None |
object_hook と似ているが、順序付きリストのペアに対して呼び出される。優先度はobject_hook より高い。 |
注意点
- 入力ファイルのエンコーディングはUTF-8、UTF-16、UTF-32のいずれかである必要があります。
- バイナリファイルも読み込めますが、エンコーディングに注意が必要です。
- 不正なJSONドキュメントを読み込もうとすると、
JSONDecodeError
が発生します。
json.loads()
: JSON形式の文字列をPythonオブジェクトに変換
json.loads()
はJSON形式の文字列をPythonオブジェクトに変換する関数です。
- 関数の定義
def loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
- 使い方
main.py
import json
# JSON形式の文字列
json_str = '{"名前": "山田太郎", "年齢": 30}'
# JSON文字列をPythonオブジェクトに変換
data = json.loads(json_str)
print(data)
print(type(data))
- 出力結果
{'名前': '山田太郎', '年齢': 30}
<class 'dict'>
引数で設定できる値
json.load()
とほぼ同じため省略。
注意点
- 入力文字列のエンコーディングはUTF-8、UTF-16、UTF-32のいずれかである必要があります。
-
bytes
型やbytearray
型の入力も受け付けますが、エンコーディングに注意が必要です。 - 不正なJSON文字列を変換しようとすると、
JSONDecodeError
が発生します。 - Python 3.9以降では、
encoding
キーワード引数は削除されています。
(番外編)JSONを読み込んで、定義したclassに適用させたい場合
**data
は辞書のキーと値をそれぞれ引数名と値として展開します。これを利用して、classに一発で適用させます。
main.py
import json
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
json_string = '{"name": "山田太郎", "age": 30}'
# 直接Personクラスのインスタンスに変換
data = json.loads(json_string)
person = Person(**data)
# 結果を表示
print(person)
print(type(person))
出力結果
Person(name='山田太郎', age=30)
<class '__main__.Person'>
注意点
- JSONのキーとクラスの属性名が完全に一致している必要があります。
- より複雑なデータ構造や、ネストされたオブジェクトがある場合は、追加の処理が必要になる可能性があります。
Discussion