序列化
程序运行中变量都在内存中,程序结束即被回收。序列化:把变量从内存变成可存储或可传输的形式(Python 称 pickling,其他语言多称 serialization)。反序列化:从序列化形式读回内存(unpickling)。Python 常用 pickle(仅 Python)和 json(跨语言、Web 标准)。
1. pickle:Python 专用序列化
import pickle。pickle.dumps(obj):把任意对象序列化为 bytes,不写文件。pickle.dump(obj, file):序列化并直接写入 file-like Object(需以'wb'等二进制模式打开)。pickle.loads(bytes):从 bytes 反序列化出对象。pickle.load(file):从 file-like Object('rb')直接反序列化出对象。- 写入磁盘的内容是二进制,人类不可读;反序列化得到的是内容相同的新对象,与原来的对象不是同一个。
import pickle
d = dict(name='Bob', age=20, score=88)
pickle.dumps(d) # bytes
with open('dump.txt', 'wb') as f:
pickle.dump(d, f)
with open('dump.txt', 'rb') as f:
d2 = pickle.load(f) # 得到与 d 内容相同的 dict
- 局限:仅适用于 Python,且不同 Python 版本可能不兼容;适合保存“不重要、反序列化失败也无所谓”的数据。
2. JSON:跨语言标准格式
- 在不同语言间传递对象,需用标准格式;JSON 是字符串,各语言都能读,便于存盘和网络传输。
import json。json.dumps(obj):把 Python 对象序列化为 str(标准 JSON 字符串)。json.dump(obj, file):序列化并写入 file-like Object。json.loads(s):把 JSON 字符串反序列化为 Python 对象。json.load(file):从 file-like Object 读取并反序列化。- JSON 标准使用 UTF-8 编码,与 Python 的 str 转换无问题。
| JSON 类型 | Python 类型 |
|---|---|
{} | dict |
[] | list |
"..." | str |
| 数字 | int / float |
| true/false | True/False |
| null | None |
import json
d = dict(name='Bob', age=20, score=88)
json.dumps(d) # '{"age": 20, "score": 88, "name": "Bob"}'
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
json.loads(json_str) # {'age': 20, 'score': 88, 'name': 'Bob'}
3. JSON 进阶:自定义类的序列化与反序列化
- dict 可直接
json.dumps();class 实例不能直接序列化,会报TypeError: ... is not JSON serializable。 - 序列化类实例:为
json.dumps(obj, default=转换函数)提供default;转换函数把任意对象变成可被 JSON 序列化的类型(通常是 dict)。
def student2dict(std):
return {'name': std.name, 'age': std.age, 'score': std.score}
json.dumps(s, default=student2dict)
- 通用写法:
json.dumps(s, default=lambda obj: obj.__dict__),利用多数实例的__dict__属性;定义了__slots__的类没有__dict__,不能这样用。 - 反序列化为类实例:
json.loads(s, object_hook=转换函数);转换函数接收 dict,返回自定义类实例。
def dict2student(d):
return Student(d['name'], d['age'], d['score'])
json.loads(json_str, object_hook=dict2student) # 得到 Student 实例
4. 中文与 ensure_ascii
json.dumps(obj, ensure_ascii=True)(默认):非 ASCII 字符(如中文)会被转成\uXXXX。json.dumps(obj, ensure_ascii=False):中文等直接保留在字符串中,便于阅读。
5. 小结
| 模块 | 适用场景 | 序列化结果 | 跨语言 / 版本 |
|---|---|---|---|
| pickle | 仅 Python 内部持久化 | bytes | 否,版本敏感 |
| json | 存盘、网络、跨语言 | str (JSON) | 是 |
- pickle:Python 专用,接口为
dumps/dump、loads/load。 - json:通用、Web 标准;
dumps/loads接口简单,通过default、object_hook可扩展为支持自定义类。
练习
对中文进行 JSON 序列化时,分别使用 ensure_ascii=True 与 ensure_ascii=False,观察输出差异。
import json
obj = dict(name='小明', age=20)
json.dumps(obj, ensure_ascii=True)
json.dumps(obj, ensure_ascii=False)