一、前言:为什么需要字典转JSON?
在Python开发中,字典(dict)是程序内部存储结构化数据的载体,只能在Python代码里读取;而JSON是互联网通用数据交换格式,接口请求、前端交互、配置文件、日志存储都必须使用JSON字符串传输。
简单区分两者:
- Python字典:Python专属数据对象,类型为
dict,支持单引号、元组、True/False/None; - JSON字符串:通用文本字符串,类型为
str,标准语法只允许双引号,布尔值为true/false,空值为null。
想要把字典对外传输、传给前端、写入配置文件,就必须将字典序列化为JSON字符串,Python官方提供内置json标准库,无需pip安装,开箱即用。
二、核心API基础讲解
json库提供两组核心方法,分「字符串操作」和「文件操作」:
json.dumps():dumps = dump string,Python对象(字典/列表)→ JSON字符串json.loads():loads = load string,JSON字符串 → Python字典/列表json.dump():不带s,Python对象直接写入JSON文件json.load():不带s,读取JSON文件转为Python对象
本文重点讲解最常用:json.dumps() 字典转JSON字符串。
三、最简基础示例(入门必看)
3.1 代码示例
# 导入内置json库
import json
# 定义标准Python字典
student_dict = {
"姓名": "小明",
"年龄": 19,
"是否在校": True,
"爱好": ["篮球", "写代码", "阅读"],
"成绩": {"语文": 92, "数学": 98}
}
# 字典转换为JSON字符串
json_result = json.dumps(student_dict)
# 打印类型与内容
print("转换后数据类型:", type(json_result))
print("JSON字符串内容:", json_result)
3.2 运行结果说明
转换后数据类型: <class 'str'>
JSON字符串内容: {"\u59d3\u540d":"\u5c0f\u660e","\u5e74\u9f84":19,"\u662f\u5426\u5728\u6821":true,"\u7231\u597d":["\u7bee\u7403","\u5199\u4ee3\u7801","\u9605\u8bfb"],"\u6210\u7ee9":{"\u8bed\u6587":92,"\u6570\u5b66":98}}
3.3 发现两个明显问题
- 所有中文全部转成
\uXXXX 转义字符,可读性极差;
下文两个核心参数专门解决这两个痛点。
四、中文正常显示 + 格式化美化
4.1 关键参数详解
ensure_ascii=False默认值True:会把中文、特殊符号转成Unicode转义字符;设置为False,中文直接正常展示,阅读体验大幅提升。indent=数字设置缩进空格数量,一般填2或4,自动换行分层格式化JSON,结构一目了然。sort_keys=True(可选) 字典按键名升序排序输出,适合统一配置类JSON,方便对比查看。
4.2 优化后完整代码
import json
student_dict = {
"姓名": "小明",
"年龄": 19,
"是否在校": True,
"爱好": ["篮球", "写代码", "阅读"],
"成绩": {"语文": 92, "数学": 98}
}
# 增加美化、中文兼容参数
json_result = json.dumps(
student_dict,
ensure_ascii=False, # 关闭中文转义
indent=4, # 4空格缩进格式化
sort_keys=True# 字典key自动排序
)
print("美化后的JSON字符串:")
print(json_result)
4.3 友好输出效果
{
"爱好": [
"篮球",
"写代码",
"阅读"
],
"成绩": {
"数学": 98,
"语文": 92
},
"年龄": 19,
"姓名": "小明",
"是否在校": true
}
五、进阶场景:包含特殊数据类型的字典转换
日常开发中字典经常包含Python独有类型:日期datetime、元组、自定义对象、Decimal小数等,直接dumps会抛出序列化报错,这里提供通用解决方案。
5.1 报错复现代码
import json
from datetime import datetime
data = {
"创建时间": datetime.now(),
"编号元组": (101, 102, 103),
"备注": None
}
# 直接转换会报错
json_str = json.dumps(data, ensure_ascii=False, indent=2)
报错信息:TypeError: Object of type datetime is not JSON serializable原因:JSON标准不支持datetime对象,库不知道如何把时间转为字符串。
5.2 解决方案:default 自定义序列化函数
default参数接收一个处理函数,遇到无法序列化的对象时自动调用,我们手动定义转换规则:
import json
from datetime import datetime
# 自定义序列化处理函数
defserialize_handler(obj):
# 判断日期类型,转为标准时间字符串
if isinstance(obj, datetime):
return obj.strftime("%Y-%m-%d %H:%M:%S")
# 其他不识别的类型抛出提示
raise TypeError(f"暂不支持序列化该类型:{type(obj)}")
data = {
"创建时间": datetime.now(),
"编号元组": (101, 102, 103),
"备注": None
}
# 传入default参数处理特殊类型
json_str = json.dumps(
data,
ensure_ascii=False,
indent=2,
default=serialize_handler
)
print(json_str)
5.3 输出结果
{
"创建时间": "2026-07-01 15:30:22",
"编号元组": [
101,
102,
103
],
"备注": null
}
补充说明:元组tuple无需额外处理,json库会自动转为JSON数组(列表)。
六、配套实用操作1:JSON字符串转回Python字典
数据是双向流转的,接口返回JSON字符串后,需要转回字典读取字段,使用json.loads():
import json
# 一段标准JSON字符串
json_text = '''
{
"姓名": "小红",
"年龄": 20,
"爱好": ["画画", "爬山"]
}
'''
# JSON字符串 → Python字典
dict_data = json.loads(json_text)
print(type(dict_data)) # <class 'dict'>
print(dict_data["姓名"]) # 小红
print(dict_data["爱好"][0]) # 画画
七、配套实用操作2:字典直接写入JSON文件
很多场景需要把字典持久化保存为.json配置文件,使用json.dump()(不带s,操作文件句柄)
import json
config_dict = {
"服务地址": "127.0.0.1",
"端口": 8080,
"开启日志": True,
"超时时间": 30
}
# w模式写入,指定utf-8防止中文乱码
with open("config.json", "w", encoding="utf-8") as f:
json.dump(
config_dict,
f,
ensure_ascii=False,
indent=2
)
执行代码后,项目目录自动生成config.json文件,内容格式化、中文正常显示。
八、压缩JSON:去除多余空格减少传输体积
前后端接口传输时,格式化缩进会增加多余空格,占用流量,通过separators参数压缩为紧凑单行:
import json
info = {"名称":"压缩测试","数值":[1,2,3]}
# separators=(分隔键值逗号, 键值冒号)
compact_json = json.dumps(info, ensure_ascii=False, separators=(',', ':'))
print(compact_json)
# 输出:{"名称":"压缩测试","数值":[1,2,3]}
九、高频踩坑问题合集
问题1:转换后中文全是\uXXXX乱码
解决:json.dumps() 添加参数 ensure_ascii=False
问题2:TypeError: xxx is not JSON serializable
解决:对象包含datetime、自定义类、Decimal等特殊类型,使用default自定义转换函数。
问题3:写入json文件打开中文乱码
解决:打开文件时必须写 encoding="utf-8"
with open("xxx.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False)
问题4:JSON字符串读取时报错JSONDecodeError
原因:JSON语法不标准,使用单引号、末尾多逗号、注释;JSON标准只支持双引号,不能写注释。
问题5:Python字典True/None 转到JSON变成什么?
映射对照表:
十、全文核心参数速查表
十一、完整可复制综合Demo
整合中文兼容、格式化、日期处理、压缩功能,可直接复制运行:
import json
from datetime import datetime
# 特殊类型处理函数
defobj_handler(obj):
if isinstance(obj, datetime):
return obj.strftime("%Y-%m-%d %H:%M:%S")
raise TypeError(f"无法序列化:{type(obj)}")
# 复合字典
data = {
"项目名称": "PythonJSON转换教程",
"创建时间": datetime.now(),
"版本号": (1, 0, 0),
"功能列表": ["字典转JSON", "JSON美化", "文件存储"],
"是否上线": True,
"备用字段": None
}
# 美化可读JSON字符串
pretty_json = json.dumps(data, ensure_ascii=False, indent=3, default=obj_handler)
print("格式化JSON:\n", pretty_json)
# 压缩传输用JSON字符串
mini_json = json.dumps(data, ensure_ascii=False, separators=(',', ':'), default=obj_handler)
print("\n压缩单行JSON:\n", mini_json)
# 写入本地JSON文件
with open("demo.json", "w", encoding="utf-8") as fp:
json.dump(data, fp, ensure_ascii=False, indent=3, default=obj_handler)