Python 序列化是指把内存中的数据结构或对象转换成可以存储或传输的格式的过程。反序列化则是把序列化后的数据恢复成原来的数据结构。序列化广泛用于数据存储、网络通信、缓存等场景。
参考文章:Python 序列化 | 简单一点学习 easyeasy.me
目录
- 什么是序列化
- 为什么需要序列化
- Python 内置的序列化模块 — pickle
- JSON 序列化
- 其他常见序列化格式简介(如 YAML、MessagePack)
- 自定义对象序列化示例
- 序列化的安全注意事项
1. 什么是序列化
序列化,就是把 Python 对象(如字典、列表、类的实例)转换成字节流或字符串,方便存储或传输。
举个简单的例子,Python 中的列表 [1, 2, 3],序列化后变成一段二进制或字符串,写入文件或发送给其他程序。
反序列化就是从这段序列化的数据还原回 Python 对象。
2. 为什么需要序列化
- 数据持久化:将对象保存到硬盘,程序关闭后还能恢复数据。
- 跨网络传输:在网络中传递数据,发送方序列化,接收方反序列化。
- 缓存:将计算结果缓存成序列化数据,下次直接读取。
- 进程间通信:不同进程或线程之间传递复杂数据结构。
3. Python 内置的序列化模块 — pickle
pickle 是 Python 标准库,支持几乎所有 Python 对象的序列化。
3.1 基本用法
import pickle
data = {'name': '小明', 'age': 20, 'scores': [88, 92, 79]}
# 序列化到文件
with open('data.pkl', 'wb') as f:
pickle.dump(data, f)
# 从文件反序列化
with open('data.pkl', 'rb') as f:
loaded_data = pickle.load(f)
print(loaded_data)
3.2 序列化到字符串
serialized = pickle.dumps(data) # 序列化为字节串
print(serialized)
original = pickle.loads(serialized) # 反序列化
print(original)
3.3 注意事项
- pickle 序列化的是 Python 专用格式,不适合跨语言使用。
- 反序列化不可信数据时有安全风险(后面会讲)。
4. JSON 序列化
json 是最常用的跨语言数据交换格式,支持字符串序列化,易于阅读。
Python 标准库中有 json 模块,适合序列化基本数据类型(字符串、数字、列表、字典等)。
4.1 基本用法
import json
data = {'name': '小红', 'age': 22, 'scores': [95, 90, 85]}
# 序列化为 JSON 字符串
json_str = json.dumps(data, ensure_ascii=False)
print(json_str)
# 反序列化
loaded = json.loads(json_str)
print(loaded)
4.2 写入文件
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False)
4.3 读取文件
with open('data.json', 'r', encoding='utf-8') as f:
data = json.load(f)
print(data)
4.4 不能直接序列化自定义对象
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
stu = Student('小强', 18)
# 直接json.dumps(stu)会报错:
# TypeError: Object of type Student is not JSON serializable
可以通过自定义编码函数解决,后面会讲。
5. 其他常见序列化格式简介
- YAML:人类可读,支持更复杂的数据结构。Python中用
PyYAML库。 - MessagePack:二进制格式,比 JSON 更紧凑,适合网络传输。
- Protobuf:Google 开发的跨语言序列化协议,适合大型项目。
这里不展开,感兴趣可以进一步了解。
6. 自定义对象序列化示例
6.1 使用 pickle 直接序列化对象
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('小丽', 30)
with open('person.pkl', 'wb') as f:
pickle.dump(p, f)
with open('person.pkl', 'rb') as f:
p2 = pickle.load(f)
print(p2.name, p2.age)
6.2 JSON 序列化自定义对象
JSON 默认不支持对象,需要自定义序列化和反序列化函数。
import json
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def person_encoder(obj):
if isinstance(obj, Person):
return {'name': obj.name, 'age': obj.age}
raise TypeError('Not serializable')
p = Person('小刚', 25)
json_str = json.dumps(p, default=person_encoder, ensure_ascii=False)
print(json_str)
# 反序列化
def person_decoder(d):
return Person(d['name'], d['age'])
p2 = json.loads(json_str, object_hook=person_decoder)
print(p2.name, p2.age)
7. 序列化的安全注意事项
- pickle 反序列化不可信数据非常危险,容易被执行恶意代码。
- 不要对来源不明的数据使用
pickle.load。 - JSON 比较安全,因为它只支持基本数据类型。
- 传输时可以加密或签名,保证数据安全和完整。
总结
Python 序列化是日常开发中非常重要的技术。通过 pickle,我们可以快速保存和恢复任意 Python 对象;通过 json,实现跨语言的数据交换。掌握序列化,能让你的程序在数据存储、网络通信、缓存等方面更加高效灵活。