首页 / 博客 / Python 格式化 JSON

Python 格式化 JSON 完整指南 2026

最后更新:2026年5月16日 · 阅读约10分钟

在 Python 中格式化 JSON 是开发者每天都会遇到的任务。不管是调试 API 响应、保存配置文件,还是生成可读的数据导出,Python 内置的 json 模块都能轻松搞定。这篇指南从基础的美化输出讲到高级的自定义编码器,帮你全面掌握。

快速提示:不想写代码就想格式化 JSON?试试我们的免费 在线 JSON 格式化工具 — 粘贴你的 JSON,立刻得到格式化好的输出。

用 json.dumps 基础格式化 JSON

在 Python 中格式化 JSON 最简单的方式就是用 json.dumps() 配合 indent 参数。这个函数会把 Python 对象转换成 JSON 格式的字符串。

import json

data = {
    "name": "Alice",
    "age": 30,
    "skills": ["Python", "JavaScript", "Go"],
    "address": {
        "city": "上海",
        "country": "中国"
    }
}

# 用 2 个空格缩进美化输出
formatted = json.dumps(data, indent=2, ensure_ascii=False)
print(formatted)

输出结果:

{
  "name": "Alice",
  "age": 30,
  "skills": [
    "Python",
    "JavaScript",
    "Go"
  ],
  "address": {
    "city": "上海",
    "country": "中国"
  }
}

indent 参数详解

indent 参数控制每一层嵌套的空格数。常用值:

# 紧凑模式(默认)
json.dumps(data)
# '{"name": "Alice", "age": 30, ...}'

# 制表符缩进
json.dumps(data, indent='\t')
# '{\n\t"name": "Alice",\n\t"age": 30,\n\t...
'

用 sort_keys 排序键名

为了输出结果一致、可复现(特别在测试和版本控制中很有用),可以使用 sort_keys 参数:

formatted = json.dumps(data, indent=2, sort_keys=True, ensure_ascii=False)
print(formatted)

这会在每一层嵌套中按字母顺序排列所有键名,方便对比不同运行的 JSON 输出。

用 json.dump 写入文件

json.dumps() 返回字符串,而 json.dump() 直接写入文件对象,处理大数据集时更省内存:

import json

data = {
    "users": [
        {"id": 1, "name": "小明"},
        {"id": 2, "name": "小红"}
    ],
    "total": 2
}

# 写入格式化的 JSON 文件
with open("output.json", "w", encoding="utf-8") as f:
    json.dump(data, f, indent=2, ensure_ascii=False)

print("JSON 已写入 output.json")

重要提示:当数据包含非 ASCII 字符(中文、日文、emoji 等)时,一定要用 ensure_ascii=False。否则 你好 会被转义成 \u4f60\u597d

处理不可序列化的类型

Python 的 json 模块只能序列化基本类型:strintfloatboolNonelistdict。其他类型需要自定义编码器。

处理 datetime 对象

这是最常见的场景。Python 的 datetime 对象默认不能被 JSON 序列化:

import json
from datetime import datetime, date

class DateTimeEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        if isinstance(obj, date):
            return obj.isoformat()
        return super().default(obj)

data = {
    "event": "Python 大会",
    "date": datetime(2026, 6, 15, 9, 0),
    "created": date(2026, 1, 1)
}

formatted = json.dumps(data, indent=2, cls=DateTimeEncoder, ensure_ascii=False)
print(formatted)

输出:

{
  "event": "Python 大会",
  "date": "2026-06-15T09:00:00",
  "created": "2026-01-01"
}

处理 Decimal 和其他数值类型

import json
from decimal import Decimal

class SmartEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Decimal):
            return float(obj)
        if isinstance(obj, set):
            return list(obj)
        if isinstance(obj, bytes):
            return obj.decode("utf-8")
        return super().default(obj)

data = {
    "price": Decimal("19.99"),
    "tags": {"python", "json", "教程"},
    "content": b"Hello World"
}

print(json.dumps(data, indent=2, cls=SmartEncoder, ensure_ascii=False))

使用 default 参数(更简单的方式)

对于一次性场景,可以直接传一个函数给 default 参数,不用创建完整的编码器类:

import json
from datetime import datetime

def serialize(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError(f"类型 {type(obj)} 不可序列化")

data = {"timestamp": datetime.now()}
print(json.dumps(data, default=serialize))

控制输出格式

自定义分隔符

separators 参数可以控制元素之间的分隔符。默认是 (', ', ': ')

# 紧凑模式,类似 JavaScript 的 JSON.stringify
compact = json.dumps(data, separators=(',', ':'))
# '{"name":"Alice","age":30}'

# 自定义分隔符
custom = json.dumps(data, separators=(' | ', ' = '))
# '{"name" = "Alice" | "age" = 30}'

保留非 ASCII 字符

data = {"greeting": "你好世界", "emoji": "🐍"}

# 默认:转义非 ASCII 字符
print(json.dumps(data))
# {"greeting": "\u4f60\u597d\u4e16\u754c", "emoji": "\ud83d\udc0d"}

# 用 ensure_ascii=False 保留 Unicode
print(json.dumps(data, ensure_ascii=False, indent=2))
# {
#   "greeting": "你好世界",
#   "emoji": "🐍"
# }

读取并格式化已有的 JSON 文件

常见的工作流是读取 JSON 文件、可能做些修改、再以格式化的方式写回去:

import json

# 读取、格式化、重写
with open("config.json", "r", encoding="utf-8") as f:
    data = json.load(f)

# 可选:修改数据
data["last_modified"] = "2026-05-16"

# 格式化写回
with open("config.json", "w", encoding="utf-8") as f:
    json.dump(data, f, indent=2, ensure_ascii=False, sort_keys=True)

进阶:美化已有的 JSON 字符串

如果你已经有一个 JSON 字符串(比如来自 API 响应),想格式化它:

import json

raw_json = '{"name":"Alice","age":30,"skills":["Python","JS"]}'

# 解析后重新格式化
parsed = json.loads(raw_json)
formatted = json.dumps(parsed, indent=2, ensure_ascii=False)
print(formatted)

命令行格式化 JSON

可以把 Python 当作终端里的 JSON 格式化工具:

# 格式化 JSON 文件
python -m json.tool input.json

# 格式化并保存
python -m json.tool input.json > formatted.json

# 从管道格式化
echo '{"a":1,"b":2}' | python -m json.tool

# 指定缩进
python -m json.tool --indent 4 input.json

# 排序键名
python -m json.tool --sort-keys input.json

性能注意事项

处理大型 JSON 文件时,记住以下几点:

json.dumps 和 json.dump 的区别

import json

data = {"key": "value"}

# 返回字符串
json_string = json.dumps(data, indent=2)

# 写入文件
with open("out.json", "w") as f:
    json.dump(data, f, indent=2)

json.dumps 常用参数速查

常见问题

如何在 Python 中美化打印 JSON?

json.dumps(data, indent=2) 就能得到格式化的 JSON 字符串。也可以用 pprint 模块,但 json.dumps 配合 indent 才是标准的 JSON 格式化方式。

json.dumps 和 json.dump 有什么区别?

json.dumps() 返回 JSON 格式的字符串。json.dump() 直接写入文件对象。需要字符串用 dumps,写文件用 dump

如何用 4 个空格缩进 JSON?

json.dumps()indent=4json.dumps(data, indent=4)

如何处理 JSON 中的 datetime 对象?

创建一个继承 json.JSONEncoder 的自定义编码器类,重写 default 方法把 datetime 转成 ISO 格式字符串,然后传 cls=YourEncoderjson.dumps()

为什么 JSON 输出中的中文字符被转义了?

默认情况下 json.dumps 设置 ensure_ascii=True,会转义非 ASCII 字符。加上 ensure_ascii=False 就能保留原始字符。

如何在命令行格式化 JSON?

用 Python 内置模块:python -m json.tool input.json。加 --sort-keys 排序输出,--indent 4 自定义缩进。

在线试试

不想写代码来格式化 JSON?试试我们的 免费在线 JSON 格式化工具 — 粘贴你的 JSON,选择缩进方式,立刻得到格式化输出。无需注册。