Python 3.0 Hacks
第11回 標準になったjsonモジュール
jsonモジュール
WebアプリケーションなどではJavaScriptと連携させることが珍しくないと思います。Python3.0および,Python2.6ではJSON(JavaScript Object Notation)をサポートするためのjsonモジュールが標準として追加されました。これにより,手軽にPythonとJavaScript間でデータのやりとりを行うことができるようになりました。
基本的な使い方
jsonモジュールの基本的な使い方はPickleと同じです。文字列にして返すにはdumps,ファイルオブジェクトの場合はdumpを使用します。同様に,文字列からPythonのオブジェクトにするためにはloadsを使用し,ファイルオブジェクトから読み込む場合にはloadを使います。
リスト1 dumpsを使った例
import json
s = json.dumps( list(range(10)) )
print( type(s), s )
リスト1実行結果
<class 'str'> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
このように,Pythonのオブジェクトを渡すとJSONに変換して文字列として返ってきます。
リスト2 loadsを使った例
t = json.loads( s )
print( type(t), t )
リスト2の実行結果
<class 'list'> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
リスト1でJSON化した文字列をPythonオブジェクトに変換するには,loadsを使用します。
リスト3 dumpを使った例
try:
from cStringIO import StringIO
except:
from io import StringIO
buf = StringIO()
json.dump( list(range(10)), buf )
buf.seek( 0 )
u = buf.read()
print( type(u), u )
リスト3の実行結果
<class 'str'> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
リスト3ではファイルオブジェクトの変わりにStringIOを使用し,そこに書き込んでいます。
リスト4 loadを使った例
buf.seek( 0 )
v = json.load( buf )
print( type(v), v )
リスト4の実行結果
<class 'list'> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
日付をエンコードする
日付をやりとりすることは多々ありますが,JSONには日付のフォーマットに関する規定はありません。そのため,jsonモジュールではdatetimeオブジェクトを直接dump,dumpsを行うことはできません。エンコーダを拡張することでエンコードを行えるようなります。
今回は“2009-05-31 06:02:20”のような形式でやりとりを行うとします。
リスト5 エンコーダの拡張
import json
from datetime import datetime
class DatetimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime ):
return obj.strftime("%Y-%m-%d %H:%M:%S")
return json.JSONEncoder.default(self, obj)
article = {'title': 'Python 3.0 Hacks', 'time': datetime.now()}
u = json.dumps(article, cls=DatetimeEncoder)
print( type(u), u )
リスト5の実行結果
<class 'str'> {"time": "2009-05-31 06:02:20", "title": "Python 3.0 Hacks"}
これでdatetimeオブジェクトからJSONへ変換することができるようになりました。
日付をデコードする
リスト5で出力した結果をそのままloadしても,日付は文字列のままでdatetimeオブジェクトにはなりません。そこで,今度は日付を読み込んだときに自動的にdatetimeにしてくれるデコード部分を書いてみます。
リスト6 デコーダ部分の作成
def toDatetime(dct):
if 'time' in dct:
dct['time'] = datetime.strptime(dct['time'], '%Y-%m-%d %H:%M:%S')
return dct
v = json.loads(u, object_hook=toDatetime)
print( type(v), v )
リスト6の実行結果
<class 'dict'> {'title': 'Python 3.0 Hacks', 'time': datetime.datetime(2009, 5, 31, 6, 2, 20)}
このように,datetimeオブジェクトに変換されていることがわかります。
まとめ
JSONに変換するモジュールは以前から存在していましたが,今回,標準モジュールとなったことで,今まで以上に気軽に使えるようになったのではないでしょうか。そして,Python3.1ではパフォーマンスの向上を目的として,jsonモジュールがC拡張モジュールとして書き直されるようです(What's New In Python 3.1)。
最近のJavaScriptのライブラリではJSONをサポートしているものが多いですし,その他の言語とのやりとりにも使えるため,JSONは今後もますます使われるライブラリのひとつになるのではないでしょうか。
Python 3.0 Hacks
- 最終回 Python 3.0座談会(動画つき)
- 第11回 標準になったjsonモジュール
- 第10回 argument"s" clinic
- 第9回 Python3にもC拡張モジュールを─Python3.0でも使える拡張モジュール開発手法の確立
- 第8回 リスト処理と内包表記
- 第7回 関数アノテーションでスマートにプラスアルファの実現
- 第6回 Pythonicな文字列フォーマットforamat()メソッド
- 第5回 multiprocessingモジュールによるプロセス間通信
- 第4回 「俺様プチencoding」を実装して理解するPython3.0のioとcodec,encodingの機構
- 第3回 turtleモジュールで図と戯れる

