9.1 认识 pickle
模块 pickle
可以将几乎任何 Python 对象保存到文件或字符串中,然后将其恢复到原来的状态。pickle
支持许多数据类型,包括用户定义的类对象,并自动化将对象转换为字节格式和反序列化的过程。
pickle
模块的主要函数
-
在文件中读写对象
-
pickle.dump(obj, file)
: 序列化对象obj
并将其写入 打开的文件file
。 -
pickle.load(file)
: 从文件file
读取并反序列化对象。
-
-
在字节数组中读写对象
-
pickle.dumps(obj)
: 序列化对象obj
并返回为字节对象。 -
pickle.loads(bytes)
: 从字节对象反序列化对象。
-
下面我们会更详细地了解它们:
9.2 文件序列化
文件序列化的主要步骤:
-
以字节写入模式打开文件
(wb)
。 -
使用
pickle.dump(obj, file)
序列化对象。 -
使用
pickle.load(file)
反序列化对象。 - 关闭文件。
文件对象的序列化和反序列化
基本上 pickle
无论是什么进行序列化。例如,这就是一个列表的序列化:
import pickle
data = [1, 2, 3, 4, 5]
# 序列化列表到文件
with open('list.pkl', 'wb') as file:
pickle.dump(data, file)
# 从文件反序列化列表
with open('list.pkl', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data) # 输出: [1, 2, 3, 4, 5]
这就是字典对象的序列化:
import pickle
# 序列化的对象示例
data = {'name': 'Alice', 'age': 30, 'is_student': False}
# 序列化对象到文件
with open('data.pkl', 'wb') as file:
pickle.dump(data, file)
# 从文件反序列化对象
with open('data.pkl', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data) # 输出: {'name': 'Alice', 'age': 30, 'is_student': False}
想保存对象 — 调用
dump()
,想加载 — 调用
load()
。没啥难的。
9.3 字符串序列化
很多时候需要通过网络传递对象,所以要把对象保存到字符串而不是文件中。为此,pickle
有 dumps
和 loads
方法,s结尾。
字符串(或字节数组)序列化和反序列化的主要步骤:
-
使用
pickle.dumps(obj)
序列化对象。 -
使用
pickle.loads(data)
反序列化对象。
字符串对象的序列化和反序列化
序列化对象到字符串(或字节数组)更简单 — 只需调用一个方法 — dumps()
。
示例:
import pickle
# 序列化的对象示例
data = {'name': 'Bob', 'age': 25, 'is_student': True}
# 序列化对象到字符串
serialized_data = pickle.dumps(data)
print(serialized_data)
# 从字符串反序列化对象
loaded_data = pickle.loads(serialized_data)
print(loaded_data) # 输出: {'name': 'Bob', 'age': 25, 'is_student': True}
9.4 序列化错误
有时候序列化会发生错误。在这种情况下,pickle
模块会抛出异常:
-
pickle.PicklingError
— 序列化时出错。 -
pickle.UnpicklingError
— 反序列化时出错。
示例:
import pickle
data = {'key': 'value'}
try:
# 序列化对象到文件
with open('data.pkl', 'wb') as file:
pickle.dump(data, file)
except pickle.PicklingError as e:
print(f"序列化错误: {e}")
try:
# 从文件反序列化对象
with open('data.pkl', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data)
except pickle.UnpicklingError as e:
print(f"反序列化错误: {e}")
通常作为开发者,在程序运行时无法处理序列化/反序列化错误。你所能做的就是将错误记录到日志,以便将来可以分析是什么原因导致的。
这些错误的主要原因是对象格式的改变。你保存了对象到文件,然后程序更新了,对象增加了新字段或删除了旧字段。然后尝试将旧对象加载到新类中…
这种情况在网络操作中很常见 —— 版本 2.18 的程序发送的对象与版本 3.1 程序期待的不太相同。这叫做 迁移问题,在长期项目中经常遇到这种情况。
GO TO FULL VERSION