JSONデータをファイルに書き込むにはどうすればいいですか?

変数dataにJSONデータを格納しています。

これをテスト用のテキストファイルに書き込んで、毎回サーバーからデータを取得する必要がないようにしたいと思います。

現在、次のようにしています。

obj = open('data.txt', 'wb')
obj.write(data)
obj.close

というエラーが出ています。

TypeError: must be string or buffer, not dict`.

これを修正するには?

ソリューション

実際のJSONの部分を忘れています。dataは辞書で、まだJSONにエンコードされていません。最大限の互換性を得るために、このように書いてください(Python 2と3)。

import json
with open('data.json', 'w') as f:
    json.dump(data, f)

最新のシステム(Python 3とUTF-8のサポートなど)では、次のようにして、より美しいファイルを書くことができます。

import json
with open('data.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=4)
解説 (21)

Python 2では、ascii-encodedではなく、utf8-encodedのファイルを取得することができます。

import io, json
with io.open('data.txt', 'w', encoding='utf-8') as f:
  f.write(json.dumps(data, ensure_ascii=False))

このコードはPython 3ではよりシンプルになります。

import json
with open('data.txt', 'w') as f:
  json.dump(data, f, ensure_ascii=False)

Windowsでは、openencoding='utf-8'という引数がまだ必要です。

データのエンコードされたコピーをメモリに保存することを避け(dumpsの結果)、Python 2と3の両方で utf8-encoded バイト文字を出力するには、次のように使用します。

import json, codecs
with open('data.txt', 'wb') as f:
    json.dump(data, codecs.getwriter('utf-8')(f), ensure_ascii=False)

codecs.getwriter コールは Python 3 では冗長ですが、Python 2 では必要です


読みやすさとサイズ:

ensure_ascii=False`を使用することで、可読性が向上し、サイズも小さくなります。

>>> json.dumps({'price': '€10'})
'{"price": "\\u20ac10"}'
>>> json.dumps({'price': '€10'}, ensure_ascii=False)
'{"price": "€10"}'

>>> len(json.dumps({'абвгд': 1}))
37
>>> len(json.dumps({'абвгд': 1}, ensure_ascii=False).encode('utf8'))
17

さらに、dumpdumps の引数にフラグ indent=4, sort_keys=True (by dinos66) を追加することで、可読性を向上させることができます。この方法では、ファイルサイズが若干大きくなりますが、jsonファイルできれいにインデントされたソート構造が得られます。

解説 (18)

それは、人間の目で見たときに読みやすいように整形したJSONファイルを書くことです。そのためには、sort_keysTrueとし、indentに4つのスペースを指定すればOKです。また、JSONファイルにアスキーコードが書き込まれないように注意してください。

with open('data.txt', 'w') as outfile:
     json.dump(jsonData, outfile, sort_keys = True, indent = 4,
               ensure_ascii = False)
解説 (5)