Pythonの標準ライブラリjson
でJSONファイルに書き込みを行うとき、こんな感じのコードになるのではないでしょうか。
import json
data = {"a": 1}
path = "path/to/mydata.json"
with open(path, "w") as f:
json.dump(data, f)
しかしこれは危険なのでやめておいた方が良いです。
json.dump
が危険な場合
シリアライズできない値がある場合を考えてみましょう。
import json
data = {"a": "ok", "b": object()} # <-- objectはシリアライズできない!
path = "path/to/mydata.json"
with open(path, "w") as f:
json.dump(data, f)
これはエラーになります。エラーになるのはいいですが、いざそのJSONファイルを覗いてみると
{"a": "ok", "b":
というふうに途中で止まっています。つまり上書きでデータが壊れるということです。これは、json.dump
ではデータを少し文字列に変換してはそれを書き込んでいるからです。
これは、たとえばアプリケーションの設定などをJSONで同じファイルに書き出しているときなんかは、JSONの場所を探して手動で修復しないとアプリケーションが開けなくなるなんて事態になり得ます。
json.dumps
を使おう
json.dump
の問題は、データを少しずつ文字列に変換してファイルに書き込んでいる点です。
json.dumps
で一度すべて文字列に変換してから、まるごとファイルに書き込めば、この問題は解決ですね。
import json
from pathlib import Path
data = {"a": "ok", "b": object()} # <-- objectはシリアライズできない!
path = "path/to/mydata.json"
data_str = json.dumps(data) # <-- ここでエラー
Path(path).write_text(data_str) # <-- ここに来る前に止まる