为什么需要序列化
底层网络传输(如 TCP/IP)本质上只认字节流,无法直接识别对象。当两个进程进行远程通信时,无论发送什么类型的数据,最终都会以二进制序列的形式在网络上传送。因此,发送方需要将对象转换为字节序列,接收方再将其恢复为对象。
简单来说:
- 序列化:将对象转换为有序的二进制序列。
- 反序列化:将二进制序列还原为对象(如字典、列表)。
- 持久化:如果序列化后的数据被保存到文件,就称为持久化。它既可以是网络传输的中间态,也可以是最终的存储形式。
Python 中的 Pickle 模块
在 Python 生态里,最经典的方案莫过于内置的 pickle 模块。不过要注意,它的局限性也很明显:仅限于两端都是 Python 的环境,且最好保持版本一致,否则容易出错。
核心方法
pickle 提供了四个基础接口,分为'内存'和'文件'两种场景:
- dumps: 对象序列化,返回字符串(内存中)。
- dump: 对象序列化到文件对象。
- loads: 对象反序列化,从字符串恢复。
- load: 对象反序列化,从文件中读取。
实战示例
下面是一个完整的读写示例。注意,文件操作必须使用二进制模式(wb / rb),否则会因为编码问题报错。
import pickle
from pathlib import Path
# 准备一些测试数据
lst = 'a b c d'.split()
d = dict(zip('abcd', range(4)))
print(f"原始数据:{lst}, {d}")
# 确保目录存在
p = Path('/root/test.pkl')
if not p.parent.exists():
p.parent.mkdir(parents=True)
# 序列化写入文件
with open(p, 'wb+') as f:
pickle.dump(lst, f)
pickle.dump(d, f)
# 反序列化读取文件
with open(p, 'rb') f:
()
(pickle.load(f))
(pickle.load(f))

