Pythonのjsonモジュール徹底解説:JSONエンコーダーとデコーダーの使い方
JSON(JavaScript Object Notation)は、軽量なデータ交換フォーマットの一つです。Pythonにはpickleというシリアライズ機構がありますが、pickleのシリアライズ形式はPython固有のものである一方、JSONは多くのプログラミング言語で実装されているため、言語間のデータ交換に広く利用されています。
Pythonの標準ライブラリに含まれるjsonモジュールは、pickleやmarshalモジュールと同様のオブジェクトシリアライズ機能を提供します。pickleモジュールと同じように、dumps()とloads()関数を使えばPythonオブジェクトをJSONエンコードされた文字列に変換でき、dump()とload()関数を使えばファイルへの書き込み・読み出しが可能です。
dumps()関数
dumps()は、PythonオブジェクトをJSON形式の文字列に変換する関数です。
loads()関数
loads()は、JSON形式の文字列を元のPythonオブジェクトに復元する関数です。
以下の例で基本的な使い方を確認してみましょう。
>>> import json
>>> data=['Rakesh',{'marks':(50,60,70)}]
>>> s=json.dumps(data)
>>> s
'["Rakesh", {"marks": [50, 60, 70]}]'
>>> json.loads(s)
['Rakesh', {'marks': [50, 60, 70]}]sort_keys引数でキーをソートする
dumps()関数にはオプション引数sort_keysを指定できます。デフォルト値はFalseですが、Trueに設定すると、辞書のキーがソートされた順序でJSON文字列に出力されます。
>>> data={"marks":50, "age":20, "rank":5}
>>> s=json.dumps(data, sort_keys=True)
>>> s
'{"age": 20, "marks": 50, "rank": 5}'
>>> json.loads(s)
{'age': 20, 'marks': 50, 'rank': 5}indent引数で整形出力する
dumps()関数にはもう一つの便利なオプション引数indentがあります。数値を指定すると、pprintモジュールの出力のように、インデントされた整形済みのJSON文字列が生成されます。値はインデントの幅(スペース数)を決定します。
>>> data = ['Rakesh',{'marks':(50,60,70)}]
>>> s = json.dumps(data, indent=2)
>>> print (s)
[
"Rakesh",
{
"marks": [
50,
60,
70
]
}
]オブジェクト指向API:JSONEncoderクラスとJSONDecoderクラス
jsonモジュールには、上記の関数に対応するオブジェクト指向APIも用意されています。モジュール内にはJSONEncoderとJSONDecoderという2つのクラスが定義されています。
JSONEncoderクラス
JSONEncoderクラスのオブジェクトは、Pythonのデータ構造をエンコードするためのエンコーダーです。各Pythonデータ型は、次の表のように対応するJSON型へ変換されます。
| Python | JSON |
|---|---|
| dict | object |
| list, tuple | array |
| str | string |
| int, float、int/float由来のEnum | number |
| True | true |
| False | false |
| None | null |
JSONEncoderクラスはJSONEncoder()コンストラクタでインスタンス化します。このクラスで定義されている主なメソッド・属性は以下の通りです。
- encode() ― PythonオブジェクトをJSON形式にシリアライズします。
- iterencode() ― オブジェクトをエンコードし、各要素のエンコード結果を順に返すイテレータを返します。
- indent ― エンコードされた文字列のインデント幅を指定します。
- sort_keys ― TrueまたはFalseを指定し、キーをソートして出力するかどうかを決定します。
- check_circular ― Trueの場合、コンテナ型オブジェクト内の循環参照をチェックします。
以下の例では、Pythonのリストオブジェクトをエンコードしています。
>>> e=json.JSONEncoder()
>>> e.encode(data)
'["Rakesh", {"marks": [50, 60, 70]}]'iterencode()メソッドを使うと、エンコード結果の各部分を順番に取得できます。
>>> for obj in e.iterencode(data):
print (obj)
[
"Rakesh"
{
"marks"
:
[
50
, 60
, 70
]
}
]JSONDecoderクラス
JSONDecoderクラスのオブジェクトは、JSON文字列をPythonのデータ構造にデコードするために使用します。このクラスの主要メソッドはdecode()です。以下のコードでは、先ほどエンコードした文字列からPythonのリストオブジェクトを復元しています。
>>> d=json.JSONDecoder()
>>> d.decode(s)
['Rakesh', {'marks': [50, 60, 70]}]ファイルやストリームとのJSONデータのやり取り
jsonモジュールには、ディスク上のファイルやバイトストリームのようなファイルライクなオブジェクトに対して、JSONデータを書き込んだり読み戻したりするためのload()およびdump()関数が定義されています。
dump()関数
dump()は、PythonオブジェクトのデータをJSON形式にエンコードし、ファイルに書き込む関数です。対象のファイルは書き込み権限を持っている必要があります。
>>> data=['Rakesh', {'marks': (50, 60, 70)}]
>>> fp=open('json.txt','w')
>>> json.dump(data,fp)
>>> fp.close()このコードを実行すると、カレントディレクトリに「json.txt」が作成され、内容は以下のようになります。
["Rakesh", {"marks": [50, 60, 70]}]load()関数
load()は、ファイルからJSONデータを読み込み、そこからPythonオブジェクトを構築する関数です。ファイルは読み取り権限付きで開く必要があります。
>>> fp=open('json.txt','r')
>>> ret=json.load(fp)
>>> ret
['Rakesh', {'marks': [50, 60, 70]}]
>>> fp.close()まとめ
本記事では、Pythonのjsonモジュールにおける重要な機能を解説しました。文字列として変換するdumps()/loads()、ファイルと直接やり取りするdump()/load()、そしてより細かい制御が可能なJSONEncoder/JSONDecoderクラスを使い分けることで、JSONデータを柔軟に扱えるようになります。Web APIとの連携や設定ファイルの管理など、さまざまな場面で活用してみてください。
-
Pythonパッケージの作成からPyPI公開まで完全ガイド|pip・setup.py・twineの使い方
Pythonには、自作コードをパッケージとして作成・公開するための非常にシンプルな仕組みが用意されています。この記事では、Pythonコードをパッケージ化し、PyPI(Python Package Index)で公開するまでの一連の手順を、初心者にもわかりやすく解説します。Pythonのパッケージ管理ツールPythonのパッケージ管理は、主に以下のツールによって行われます。pip:最も広く使われているパッケージ管理ツールです。OSへの手動インストールや更新作業をほぼ不要にし、パッケージとそのバージョン番号のリストを管理することで、別環境への正確な再現(複製)を可能にします。Python Pac
-
Pythonの辞書をJSON形式で出力・表示する方法
JSONとはJSON(JavaScript Object Notation)は、データをテキスト形式で表現するための軽量なデータ交換フォーマットです。Web APIや設定ファイルなど、さまざまな場面で広く利用されています。jsonモジュールとdumps()関数Pythonには標準ライブラリとしてjsonモジュールが用意されており、JSONデータのエンコード(書き出し)とデコード(読み込み)を簡単に行うことができます。このモジュールのdumps()関数を使用すると、Pythonの辞書オブジェクトをそのままJSON形式の文字列に変換できます。基本的な使い方D1={pen:25, pencil:10