Python 中的 json
模块是处理 JSON(JavaScript Object Notation)格式数据的利器,它轻便、易读,在 Web 通信、配置管理和数据存储等场景非常常用。
下面这张表格可以帮助你快速了解 Python 的 json
模块。
模块组件 | 类别 | 功能描述 | 常用场景 |
| 函数 | 将 Python 对象序列化为 JSON 格式的字符串。 | 数据网络传输(如 API 请求) |
| 函数 | 将 JSON 字符串反序列化为 Python 对象。 | 解析接收到的 JSON 字符串(如 API 响应) |
| 函数 | 将 Python 对象序列化并直接写入文件。 | 保存数据到配置文件 |
| 函数 | 从文件中读取 JSON 数据并反序列化为 Python 对象。 | 读取配置文件或本地数据文件 |
🔄 JSON 与 Python 的数据类型映射
JSON 和 Python 的数据类型并非一一对应,理解它们之间的转换关系至关重要。
JSON 数据类型 | Python 数据类型 (序列化) | Python 数据类型 (反序列化) |
对象 ( |
|
|
数组 ( |
|
|
字符串 |
|
|
数字 |
|
|
|
|
|
|
|
|
注意:JSON 的字符串必须使用双引号("..."
),Python 中的单引号字符串在序列化后会被转换为双引号。
⚙️ 核心函数详解
1. 序列化:json.dumps()
json.dumps()
将 Python 对象(如字典、列表)转换为 JSON 格式的字符串。
import json
data = {
"name": "张三",
"age": 30,
"hobbies": ["阅读", "编程"],
"is_student": False
}
json_str = json.dumps(data)
print(json_str)
# 输出: {"name": "\u5f20\u4e09", "age": 30, "hobbies": ["\u9605\u8bfb", "\u7f16\u7a0b"], "is_student": false}
常用参数:
ensure_ascii=True
:默认为True
,中文字符会被转义为\uXXXX
形式。设为False
可原样输出中文。
json_str_chinese = json.dumps(data, ensure_ascii=False)
print(json_str_chinese) # 输出: {"name": "张三", ...}
indent
:指定缩进空格数,使输出的 JSON 字符串更易读。
json_str_pretty = json.dumps(data, ensure_ascii=False, indent=4)
sort_keys
:设为True
时,输出的字典按键名排序。
2. 反序列化:json.loads()
json.loads()
将包含 JSON 数据的字符串解析为 Python 对象。
json_string = '{"name": "李四", "age": 25, "scores": [95, 87, 92]}'
python_data = json.loads(json_string)
print(python_data['name']) # 输出: 李四
print(python_data['scores'][0]) # 输出: 95
3. 文件操作:json.dump()
与 json.load()
这两个函数用于直接与文件交互。
- 写入 JSON 文件:使用
json.dump()
。
data_to_save = {"company": "Apple", "symbol": "AAPL"}
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data_to_save, f, ensure_ascii=False, indent=2)
- 读取 JSON 文件:使用
json.load()
。
with open('data.json', 'r', encoding='utf-8') as f:
data_loaded = json.load(f)
print(data_loaded)
强烈建议使用 with open() as ...
语法来确保文件正确关闭。
🚀 处理复杂数据类型与高级技巧
JSON 标准不支持 Python 的所有数据类型,如 datetime
对象或 set
集合。处理这些类型需要一些技巧。
1. 自定义序列化:default
参数
可以通过 default
参数指定一个函数,该函数负责将不支持的类型转换为可序列化的类型(如将 datetime
转为字符串,将 set
转为 list
)。
import json
from datetime import datetime
data_with_special_types = {
"event": "Meeting",
"time": datetime.now(), # datetime 对象,JSON 不支持
"participants": {"Alice", "Bob"} # 集合,JSON 不支持
}
def custom_serializer(obj):
"""自定义序列化函数"""
if isinstance(obj, datetime):
return obj.isoformat() # 转换为 ISO 8601 字符串
elif isinstance(obj, set):
return list(obj) # 转换为列表
else:
raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
json_str = json.dumps(data_with_special_types, default=custom_serializer)
print(json_str) # 输出: {"event": "Meeting", "time": "2023-10-25T10:30:00.123456", "participants": ["Alice", "Bob"]}
一个简单的备选方案是使用 default=str
,它会尝试将所有非标准类型转换为字符串,但控制力较弱。
2. 自定义反序列化:object_hook
参数
在反序列化时,可以使用 object_hook
参数提供一个函数,在将 JSON 对象转换为 Python 字典后,可以对这个字典进行进一步处理,例如将其转换为自定义类的实例。
🔒 错误处理与安全实践
- 处理异常:在解析不可信来源的 JSON 数据时,可能会遇到格式错误。
invalid_json_str = '{"name": "John", "age": }' # 无效的 JSON
try:
data = json.loads(invalid_json_str)
except json.JSONDecodeError as e:
print(f"JSON 解析错误: {e}")
- 安全警告:
json.loads()
和json.load()
功能强大,但不要直接用它们解析来自不可信来源(如用户输入)的 JSON 字符串,以防潜在的安全风险。对于复杂数据交换,应考虑更安全的数据格式。
💡 实际应用场景
- Web API 交互:在前后端分离的应用中,前端通过 AJAX 发送 JSON 数据,Python 后端使用
json.loads()
解析请求,处理后再用json.dumps()
返回 JSON 响应。 - 配置文件管理:许多应用程序使用
.json
文件来存储配置信息,因其结构清晰,易于读写和修改。 - 数据持久化:可以将程序运行中的中间结果或状态以 JSON 格式保存到本地文件,下次启动时再读取恢复。
💎 总结
Python 的 json
模块简单易用且功能强大。掌握其核心函数、数据类型映射以及处理复杂情况的方法,能让你在数据交换、配置管理和应用状态保存等任务中得心应手。
希望这份介绍能帮助你全面掌握 Python 中的 JSON 处理。如果你有任何疑问,欢迎随时提出。