在Python开发中,经常需要把程序运行产生的字典数据保存下来,方便下次启动读取或与其他系统交换。JSON作为一种轻量级的数据交换格式,天然适合表达字典结构。借助标准库中的json模块,我们可以非常方便地完成字典到JSON文件的转换与存储。

一、使用json.dump直接写入文件
json.dump函数能够将Python字典对象直接序列化并写入一个已打开的文件对象,是最常用的写法。它的优势在于不需要在内存中先生成完整的字符串,而是边序列化边写盘,适合数据量较大的场景。
下面是一段基础示例,展示如何把一个包含中文的字典写入到本地文件:
import json
user_info = {
'name': '张三',
'age': 28,
'skills': ['Python', 'SQL', 'Linux']
}
# 以写入模式打开文件,指定编码避免Windows下乱码
with open('user.json', 'w', encoding='utf-8') as f:
json.dump(user_info, f, ensure_ascii=False, indent=4)
上面的代码中,ensure_ascii=False让中文以原文形式写出,而不是默认的uXXXX格式;indent=4则让文件内容带缩进,便于人眼阅读。如果省略这两个参数,生成的文件会是紧凑的一行且中文被转义。
需要注意的是,open函数中的encoding='utf-8'非常关键。在部分操作系统上,若不明确指定编码,文件会以系统默认编码写入,再次用其他工具读取时可能出现乱码或解析错误。
二、使用json.dumps配合手动写文件
如果你希望先拿到JSON字符串,再做些额外处理,比如打印日志、通过网络发送,或者拼接其他内容,就可以用json.dumps把字典变成字符串,再自行写入文件。
这种方式在需要复用序列化结果时更灵活,但会多占用一份字符串内存。示例代码如下:
import json
config = {
'debug': True,
'host': '127.0.0.1',
'port': 8080
}
# 先序列化为字符串
text = json.dumps(config, ensure_ascii=False, indent=2)
# 手动写入文件
with open('config.json', 'w', encoding='utf-8') as f:
f.write(text)
从功能上看,dump相当于dumps加write的组合。在简单落盘场景下,直接用dump更简洁;而在需要多次使用同一份序列化文本时,dumps能避免重复序列化开销。
两者在参数上基本一致,都支持skipkeys、check_circular、allow_nan等高级选项。例如当字典的键不是字符串类型时,设置skipkeys=True可以跳过无法序列化的键而不抛异常。
三、异常处理与写入安全
实际项目中,写文件可能因磁盘满、权限不足或路径不存在而失败。如果不捕获异常,整个脚本会中断。因此生产代码应当包裹异常处理逻辑。
以下示例演示了如何安全地写入JSON,并在出错时给出提示而不崩溃:
import json
import os
data = {'status': 'ok', 'code': 200}
file_path = './output/result.json'
try:
# 确保目录存在
os.makedirs(os.path.dirname(file_path), exist_ok=True)
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
except OSError as e:
print('文件写入失败:' + str(e))
except TypeError as e:
print('数据无法序列化:' + str(e))
这里先用os.makedirs创建上级目录,避免因为文件夹不存在而报FileNotFoundError。OSError涵盖了大多数系统级读写错误,TypeError则用于捕获字典里包含不支持类型(如函数、自定义对象未定义编码器)的情况。
对于包含datetime、Decimal等类型的字典,标准json无法直接处理,需要自定义JSONEncoder或通过default参数提供转换函数,否则写入时会抛出TypeError。
四、常见误区与注意事项
不少人在写入JSON后,用普通记事本打开发现中文变成u4e2du6587,就以为是代码写错了。其实这是ensure_ascii默认值为True导致的,并非文件损坏,只是ASCII安全转义。
另一个容易忽略的点是,字典里的True、False、None在JSON中对应true、false、null。json模块会自动完成这种映射,但如果你手动拼接字符串,就必须自己转换,否则生成的不是合法JSON。
如果字典嵌套层级很深或体积很大,建议不要一次性dumps到内存再写,而是用dump流式写出,并考虑临时文件写法(先写tmp再rename)来保证存储过程的原子性,防止程序崩溃留下半个JSON文件。
五、小结对比
为了更直观地选择方案,可以参考下面的对比表:
| 方法 | 适用场景 | 内存占用 | 代码复杂度 |
|---|---|---|---|
| json.dump | 直接落盘、简单存储 | 较低 | 低 |
| json.dumps+write | 需复用字符串、二次处理 | 较高 | 中 |
总体来看,Python把字典写入JSON文件并不复杂,核心就是选对接口、设好编码与ensure_ascii,并加上必要的异常保护。掌握这些细节后,无论是写配置文件还是导出接口数据,都能稳定可靠地完成。