Python json.dump()とは?JSONファイルに書き込む方法

Pythonのjson.dump()は、辞書やリストをJSONファイルに書き込む関数です。

「Pythonのデータを.jsonファイルに保存したい」という場面で使います。


json.dump()の基本的な使い方

import json

data = {"name": "テックジム", "count": 3}

with open("out.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

print(open("out.json", encoding="utf-8").read())

実行結果:

{
  "name": "テックジム",
  "count": 3
}

引数は「データ、ファイルオブジェクト」の順です。逆にすると動きません。

import json

# NG: 順序が逆
json.dump(f, data)

# OK
json.dump(data, f)

dumps()との違い

json.dump() json.dumps()
出力先 ファイル 文字列
戻り値 なし str
ファイルオブジェクト 必要 不要

末尾のsが「string」と覚えると混同しません。

import json

data = {"a": 1}

# 文字列が欲しい
s = json.dumps(data)

# ファイルに書きたい
with open("out.json", "w", encoding="utf-8") as f:
    json.dump(data, f)

次の書き方でも同じ結果になります。

import json
from pathlib import Path

Path("out.json").write_text(json.dumps(data, ensure_ascii=False), encoding="utf-8")

dumps()については「Python json.dumps()とは?辞書をJSON文字列に変換する方法」をご覧ください。


日本語がテになる

import json

data = {"name": "テックジム"}

with open("a.json", "w", encoding="utf-8") as f:
    json.dump(data, f)

print(open("a.json", encoding="utf-8").read())

実行結果:

{"name": "テックジム"}

既定ではASCII以外をすべてエスケープします。データとしては正しく、読み込めば元に戻りますが、ファイルを開いても内容が読めません。

ensure_ascii=Falseを指定してください。

import json

with open("a.json", "w", encoding="utf-8") as f:
    json.dump({"name": "テックジム"}, f, ensure_ascii=False)

print(open("a.json", encoding="utf-8").read())

実行結果:

{"name": "テックジム"}

encodingを2か所で意識する

間違えやすい点です。encodingはopen()に、ensure_asciiはjson.dump()に指定します。

import json

with open("a.json", "w", encoding="utf-8") as f:   # ← ファイルの文字コード
    json.dump(data, f, ensure_ascii=False)          # ← 日本語をそのまま出すか

json.dump()にencoding引数はありません。指定するとエラーになります。

TypeError: __init__() got an unexpected keyword argument 'encoding'

また、open()でencodingを省略するとWindowsではcp932になり、ensure_ascii=Falseと組み合わせたときに書き込みが失敗することがあります。両方セットで指定するのが確実です。


保存先のフォルダは自動で作られない

import json
from pathlib import Path

out = Path("output/2026/data.json")
out.parent.mkdir(parents=True, exist_ok=True)

with out.open("w", encoding="utf-8") as f:
    json.dump({"a": 1}, f, ensure_ascii=False)

print(out)

実行結果:

output/2026/data.json

フォルダがないとFileNotFoundErrorになります。parent.mkdir(parents=True, exist_ok=True)とセットで書いてください。


途中で失敗するとファイルが壊れる

最も注意すべき点です。

import json

# 危険:書き込み中に失敗すると設定ファイルが壊れる
with open("config.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False)

open(..., "w")を実行した時点で元の内容は消えます。その後に例外が起きると、中身が空、あるいは途中までのJSONが残ります。

次回の読み込みはJSONDecodeErrorで失敗し、設定が失われます。

変換できない型が混ざっていると、まさにこれが起こります。

import json
import datetime

data = {"a": 1, "b": 2, "created": datetime.date(2026, 9, 16)}

with open("broken.json", "w", encoding="utf-8") as f:
    json.dump(data, f)

実行結果:

TypeError: Object of type date is not JSON serializable

このときbroken.jsonには{"a": 1, "b": 2, "created": という途中までの内容が書き込まれています。

一時ファイル+replace()で安全に

import json
import os
from pathlib import Path

data = {"name": "テックジム", "version": 2}

target = Path("config.json")
tmp = target.with_name(target.name + ".tmp")

with tmp.open("w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

os.replace(tmp, target)

print(target.read_text(encoding="utf-8"))

実行結果:

{
  "name": "テックジム",
  "version": 2
}

この書き方なら、どの時点で中断されてもconfig.jsonは無事です。

  • 書き込み中に失敗 → 本体は古いまま無事
  • replace()のあと → 完全に新しい内容

一時ファイルは本番と同じフォルダに作ってください。別ドライブだと入れ替えが一瞬で終わらず、この性質が失われます。

詳しくは「Python os.replace()とは?ファイルを安全に上書き移動する方法」をご覧ください。


変換できない型への対処

import json
import datetime
from decimal import Decimal

def encoder(o):
    if isinstance(o, (datetime.date, datetime.datetime)):
        return o.isoformat()
    if isinstance(o, Decimal):
        return float(o)
    if isinstance(o, set):
        return sorted(o)
    raise TypeError(f"{type(o).__name__} は変換できません")

data = {"created": datetime.date(2026, 9, 16), "price": Decimal("1.5")}

with open("out.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, default=encoder)

print(open("out.json", encoding="utf-8").read())

実行結果:

{"created": "2026-09-16", "price": 1.5}

defaultに変換できない値を受け取って変換後の値を返す関数を渡します。


追記はできない

import json

# NG: 追記モードで書いても正しいJSONにならない
with open("log.json", "a", encoding="utf-8") as f:
    json.dump({"event": "login"}, f)
    json.dump({"event": "logout"}, f)

ファイルの中身は{"event": "login"}{"event": "logout"}となり、JSONとして読み込めません。

ログのように追記したい場合は、1行に1つのJSONを書く形式(JSON Lines)を使います。

import json

events = [{"event": "login"}, {"event": "logout"}]

with open("log.jsonl", "w", encoding="utf-8") as f:
    for e in events:
        f.write(json.dumps(e, ensure_ascii=False) + "\n")

with open("log.jsonl", encoding="utf-8") as f:
    for line in f:
        print(json.loads(line))

実行結果:

{'event': 'login'}
{'event': 'logout'}

この形式なら追記でき、1行ずつ読めるため巨大なログでもメモリを圧迫しません。


json.dump()のまとめ

  • json.dump(データ, ファイル)でJSONファイルに書き込む
  • 引数の順序は「データが先」
  • 日本語はensure_ascii=False、整形はindent
  • encodingはopen()に指定する(dump()には引数がない)
  • 保存先のフォルダは自動で作られない
  • 途中で失敗するとファイルが壊れる。一時ファイル+replace()が安全
  • 変換できない型はdefaultで指定する
  • 追記はできない。ログにはJSON Lines形式を使う

あわせて読みたい

プログラミング学習に興味がある方は、まずは無料体験会へ

無料体験会・お申し込みはこちら