1. 什么是 Pickling 和 Unpickling?
- Pickling: 将 Python 对象序列化为字节流的过程,以便存储到文件或通过网络传输。
- Unpickling: 将字节流反序列化为 Python 对象的过程,恢复原始数据。
- Pickling 和 Unpickling 是 Python 中实现对象持久化的核心机制。
2. 使用场景
-
数据持久化:将对象保存到文件中,以便后续使用。
-
进程间通信:在多进程编程中传递复杂对象。
-
缓存:将计算结果序列化后存储,避免重复计算。
3. 实现方式
Python 提供了 pickle 模块来实现 Pickling 和 Unpickling。
3.1 Pickling 示例
import pickle
data = {
"name": "Alice",
"age": 30,
"hobbies": ["reading", "traveling"]
}
# 将对象序列化为字节流
with open("data.pkl", "wb") as file:
pickle.dump(data, file)
3.2 Unpickling 示例
import pickle
# 将字节流反序列化为对象
with open("data.pkl", "rb") as file:
loaded_data = pickle.load(file)
print(loaded_data)
输出:
{'name': 'Alice', 'age': 30, 'hobbies': ['reading', 'traveling']}
4. 支持的 Python 对象类型
pickle 模块支持大多数 Python 对象类型,包括:
- 基本数据类型(如 int、float、str、list、dict)。
- 自定义类和对象。
- 函数和类定义(需在反序列化时能访问到)。
5. 注意事项
5.1 安全性
风险:反序列化不可信数据可能导致代码执行(如恶意构造的 Pickle 数据)。
防护措施:
- 仅反序列化可信来源的数据。
- 使用 pickle.HIGHEST_PROTOCOL 提高安全性。
5.2 性能
-
Pickling 和 Unpickling 的性能取决于数据大小和复杂度。
-
对于大型数据集,建议使用更高效的序列化工具(如 json、msgpack)。
5.3 跨语言兼容性
-
pickle 是 Python 特有的格式,无法直接与其他语言交互。
-
如果需要跨语言兼容,可以使用 json 或 protobuf。
6. 高级用法
6.1 自定义类的 Pickling
通过实现 getstate 和 setstate 方法,可以控制类的序列化和反序列化行为。
示例:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __getstate__(self):
return {"name": self.name, "age": self.age}
def __setstate__(self, state):
self.name = state["name"]
self.age = state["age"]
# Pickling
person = Person("Alice", 30)
with open("person.pkl", "wb") as file:
pickle.dump(person, file)
# Unpickling
with open("person.pkl", "rb") as file:
loaded_person = pickle.load(file)
print(loaded_person.name, loaded_person.age) # 输出:Alice 30
6.2 使用 dumps 和 loads
- pickle.dumps(obj):将对象序列化为字节流(不写入文件)。
- pickle.loads(bytes):将字节流反序列化为对象。
示例:
import pickle
data = {"key": "value"}
serialized = pickle.dumps(data) # 序列化为字节流
deserialized = pickle.loads(serialized) # 反序列化为对象
print(deserialized) # 输出:{'key': 'value'}
7. 总结
- Pickling 和 Unpickling 是 Python 中实现对象序列化和反序列化的核心机制。
- 适用于数据持久化、进程间通信和缓存等场景。
- 使用时需注意安全性和性能问题,必要时可选择其他序列化工具。