对象的序列化和反序列化
对象的序列化和反序列化
一、概念与应用场景导入
什么是序列化和反序列化?
- 序列化(Serialization):将对象转为可存储或传输的格式(如字符串、字节流)。
- 反序列化(Deserialization):将这些格式恢复为原始对象。
使用场景
场景 | 示例 |
---|---|
数据持久化 | 将字典或列表保存为 JSON 文件 |
网络通信 | 后端返回给前端 JSON 数据 |
远程调用 | 分布式系统中的服务间对象传输 |
缓存存储 | 将结构化对象写入 Redis 等缓存系统 |
二、JSON 概述与特点
什么是 JSON?
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,具有以下特点:
- 使用键值对(key-value)组织数据
- 可嵌套数组与对象
- 是纯文本,语言无关,平台无关
为什么选择 JSON?
- 可读性强,结构清晰
- 与大多数编程语言有良好兼容性
- 是 Web API 数据传输的事实标准
JSON 与 Python 的类型映射关系
JSON 类型 | Python 类型 |
---|---|
object |
dict |
array |
list |
string |
str |
number |
int / float |
boolean |
bool |
null |
None |
三、使用 json
模块进行序列化与反序列化
Python 提供标准库 json
处理 JSON 数据。
核心函数
函数 | 说明 |
---|---|
json.dump() |
对象 ➜ JSON ➜ 写入文件 |
json.dumps() |
对象 ➜ JSON ➜ 字符串 |
json.load() |
从文件读取 JSON ➜ 转为对象 |
json.loads() |
从字符串读取 JSON ➜ 转为对象 |
示例 1:将对象写入 JSON 字符串
import json
data = {'name': '骆昊', 'age': 40, 'hobbies': ['阅读', '编程']}
json_str = json.dumps(data)
print(json_str)
示例 2:将对象保存为 JSON 文件
with open('profile.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
ensure_ascii=False
可输出中文,indent=2
使格式更易读。
示例 3:从文件读取 JSON
with open('profile.json', 'r', encoding='utf-8') as f:
restored_data = json.load(f)
print(restored_data)
四、最佳实践与注意事项
✅ 建议做法:
- 使用
with open(...)
管理文件资源 - 使用
ensure_ascii=False
保留原始字符 - 尽可能使用
indent
格式化输出以便调试 - 用
try...except
包裹load
/dump
操作处理错误
⚠️ 常见问题:
问题 | 原因与解决 |
---|---|
中文变成 \uXXXX |
加 ensure_ascii=False |
写入失败 | 文件未用 'w' 模式打开或权限不足 |
JSONDecodeError | 文件内容不是合法 JSON |
五、ujson
:性能更高的 JSON 处理库
为什么用 ujson
?
- 比标准库
json
更快,适合大数据量序列化场景
安装方法:
pip install ujson
使用方式几乎与 json
一致:
import ujson
data = {'score': 98}
with open('score.json', 'w') as f:
f.write(ujson.dumps(data))
注意:
ujson
不支持所有json
参数(如indent
),需根据项目需求评估兼容性。
六、结合网络 API:从 Web 获取 JSON 数据
推荐库:requests
安装:
pip install requests
示例:获取新闻 JSON 数据
import requests
url = 'http://api.tianapi.com/guonei/?key=你的APIKey&num=5'
resp = requests.get(url)
if resp.status_code == 200:
news_data = resp.json()
for item in news_data.get('newslist', []):
print(item['title'], item['url'], sep='\n')
print('-' * 50)
说明:
requests.get()
发送 HTTP 请求resp.json()
自动解析 JSON 响应为字典- 结合 JSON 反序列化实现数据展示与交互
七、序列化进阶补充:pickle
与 shelve
简要比较:
模块 | 优势 | 劣势 |
---|---|---|
json |
可读性强、跨语言兼容 | 仅支持基础数据类型 |
pickle |
支持 Python 任意对象 | 只能用于 Python,安全性差 |
shelve |
类似小型键值数据库 | 仅用于 Python,对象兼容有限 |
示例:pickle
序列化对象
import pickle
with open('obj.pkl', 'wb') as f:
pickle.dump(data, f)
with open('obj.pkl', 'rb') as f:
obj = pickle.load(f)
print(obj)
适用于纯 Python 项目内部缓存或对象传输,不建议用于 Web 或存储敏感信息。
八、总结与建议
✅ 应用建议:
- Web 开发与数据交互:优先使用
json
(推荐配合requests
) - 数据持久化与配置文件:优先使用
json
,结合with
与try
- 性能优化场景:尝试
ujson
- 内部对象缓存(非跨语言):可使用
pickle
或shelve
❌ 避免误区:
- 不要用
pickle
处理来自不可信来源的数据(可能执行恶意代码) - 不要用 JSON 保存自定义对象(需先转换为
dict
格式) - 复杂嵌套数据结构不建议手动拼 JSON 字符串,请使用序列化函数
如需进一步学习 jsonschema
进行数据结构验证,或实现 JSON-RPC 通信协议,欢迎继续提问!