下面我将从基础到高级,详细解释如何进行 Unicode 到 JSON 的转换。

核心结论(TL;DR)
对于绝大多数情况,你只需要这样做:
import json
# 你的 Python 字典,其中包含 Unicode 字符串
data = {
"name": "张三",
"city": "北京",
"description": "这是一个包含中文和特殊符号 € 的描述。"
}
# 将 Python 对象转换为 JSON 字符串
json_string = json.dumps(data)
print(json_string)
# 输出: {"name": "张三", "city": "北京", "description": "这是一个包含中文和特殊符号 € 的描述。"}
json.dumps() 会自动处理所有 Python 字符串(在 Python 3 中,str 类型就是 Unicode 字符串),并将其正确编码为 JSON 字符串。
详细解释
Python 3 的 Unicode 优势
最重要的一点是:在 Python 3 中,所有字符串都是 Unicode 字符串,当你写下 "你好" 时,它就是一个 Unicode 字符串,Python 的 json 模块默认使用 UTF-8 编码,所以当你调用 json.dumps() 时,它会自动将这些 Unicode 字符串序列化为符合 JSON 标准的 UTF-8 编码字符串。
这解决了 Python 2 中最常见的问题(str vs unicode),使得整个过程变得非常简单。

json.dumps() 的关键参数
虽然 json.dumps() 很简单,但了解几个关键参数可以帮助你更好地控制输出格式:
-
ensure_ascii(默认:True)True(默认): 这是 最关键 的参数,当ensure_ascii=True时,json.dumps()会将所有非 ASCII 字符(如中文、€、©)转换为它们的 Unicode 转义序列(\u4e2d\u6587),这确保生成的 JSON 字符串只包含 ASCII 字符,在某些只支持 ASCII 的旧系统或传输协议中非常有用。False: 如果你希望保留原始的 Unicode 字符(比如中文),就必须设置ensure_ascii=False。这是处理中文等非英语文本时最推荐的设置。
-
indent(默认:None)None: 输出紧凑的单行 JSON,没有格式化。- 一个整数 (如
2,4): 输出格式化、易读的 JSON,缩进由该整数指定。
-
ensure_ascii=False和indent的组合使用
(图片来源网络,侵删)
这是生成美观、可读且支持多语言的 JSON 的最佳实践。
import json
data = {
"name": "李四",
"details": {
"city": "上海",
"hobbies": ["阅读", "旅行", "编程"]
}
}
# 生成紧凑的、ASCII转义的JSON (默认)
compact_json = json.dumps(data)
print("紧凑 (默认):")
print(compact_json)
# 输出: {"name": "李四", "details": {"city": "上海", "hobbies": ["阅读", "旅行", "编程"]}}
# 生成易读的、保留Unicode的JSON (推荐)
pretty_json = json.dumps(data, ensure_ascii=False, indent=4)
print("\n易读 (推荐):")
print(pretty_json)
# 输出:
# {
# "name": "李四",
# "details": {
# "city": "上海",
# "hobbies": [
# "阅读",
# "旅行",
# "编程"
# ]
# }
# }
处理中文编码问题(写入文件)
当你需要将 JSON 字符串写入文件时,强烈建议显式指定编码为 UTF-8,虽然 Python 3 的默认编码通常是 UTF-8,但显式指定可以避免在不同环境或系统上可能出现的潜在问题。
import json
data = {"message": "你好,世界!"}
# 1. 先 dumps 得到 JSON 字符串
json_string = json.dumps(data, ensure_ascii=False)
# 2. 再写入文件,指定 encoding='utf-8'
with open('data.json', 'w', encoding='utf-8') as f:
f.write(json_string)
# 为了验证,我们可以读取回来
with open('data.json', 'r', encoding='utf-8') as f:
loaded_data = json.load(f)
print(loaded_data)
# 输出: {'message': '你好,世界!'}
更简洁的写法:json.dump()
json 模块还提供了一个 dump() 函数,它可以直接将 Python 对象写入文件流,无需手动 dumps 再写入。
import json
data = {"message": "你好,世界!"}
# 直接 dump 到文件,一步到位,并确保编码正确
with open('data_direct.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
反向操作:从 JSON 加载为 Python 对象
当你从 JSON 字符串或文件加载数据时,json.load() 或 json.loads() 会自动将 JSON 字符串解码为 Python 的 Unicode 字符串(str 类型)。
import json
json_string = '{"name": "王五", "city": "广州"}'
# 从字符串加载
data_from_string = json.loads(json_string)
print(data_from_string['name']) # 输出: 王五 (这是一个Python str)
# 从文件加载
with open('data.json', 'r', encoding='utf-8') as f:
data_from_file = json.load(f)
print(data_from_file['message']) # 输出: 你好,世界! (这也是一个Python str)
总结与最佳实践
| 场景 | 推荐方法 | 说明 |
|---|---|---|
| 生成 JSON 字符串 | json.dumps(data, ensure_ascii=False, indent=4) |
ensure_ascii=False 保留非ASCII字符,indent 使其易读,这是处理中文等语言的标准做法。 |
| 将 JSON 写入文件 | json.dump(data, f, ensure_ascii=False, indent=4) |
直接写入文件流,更高效。务必使用 with open(..., encoding='utf-8')。 |
| 从 JSON 字符串解析 | json.loads(json_string) |
自动将 JSON 解码为 Python 的 Unicode 字符串。 |
| 从 JSON 文件解析 | json.load(f) |
自动从文件流中读取并解码。务必使用 with open(..., encoding='utf-8')。 |
在 Python 3 中,你几乎不需要担心 Unicode 的底层编码问题。json 模块已经为你处理好了,你只需要记住 ensure_ascii=False 这个关键参数,就能轻松地生成包含中文等非英语字符的、标准且美观的 JSON 数据。
