Python 对象序列化 (Pickle)
术语"对象序列化"是指将对象的状态转换为字节流的过程。创建后,此字节流可以进一步存储在文件中或通过套接字等传输。另一方面,从字节流重建对象称为反序列化。
Python 中序列化和反序列化的术语分别是 pickling 和 unpickling。Python 标准库中的 pickle 模块提供序列化 (dump() 和 dumps()) 和反序列化 (load() 和 loads()) 函数。
pickle 模块使用非常 Python 特定的数据格式。因此,不是用 Python 编写的程序可能无法正确反序列化编码 (pickled) 数据。此外,从未经身份验证的来源解开数据也不被认为是安全的。
pickle 协议
协议是用于将 Python 对象构造为二进制数据或从二进制数据解构 Python 对象的约定。目前,pickle 模块定义了 5 种不同的协议,如下所示 −
协议版本 0 | 原始"人类可读"协议向后兼容早期版本。 |
协议版本 1 | 旧二进制格式也与早期版本的 Python 兼容。 |
协议版本 2 | 在 Python 2.3 中引入,可高效地对新式类进行 pickle。 |
协议版本 3 | 在 Python 3.0 中添加。当需要与其他 Python 3 版本兼容时推荐使用。 |
协议版本 4 | 在 Python 3.4 中添加。它增加了对非常大对象的支持 |
要了解 Python 安装的最高和默认协议版本,请使用 pickle 模块中定义的以下常量
>>> import pickle >>> pickle.HIGHEST_PROTOCOL 4 >>> pickle.DEFAULT_PROTOCOL 3
如前所述,pickle 模块的 dump() 和 load() 函数执行对 Python 数据的 pickle 和 unpickling。dump() 函数将 pickle 对象写入文件,load() 函数将文件中的数据 unpickle 到 Python 对象。
以下程序将字典对象 pickle 到二进制文件中。
import pickle f = open("data.txt","wb") dct = {"name":"Ravi", "age":23, "Gender":"M","marks":75} pickle.dump(dct,f) f.close()
执行上述代码时,字典对象的字节表示将存储在 data.txt 文件中。
要将二进制文件中的数据反序列化或反序列化回字典,请运行以下程序
import pickle f = open("data.txt","rb") d = pickle.load(f) print (d) f.close()
Python 控制台显示从文件读取的字典对象
{'age': 23, 'Gender': 'M', 'name': 'Ravi', 'marks': 75}
pickle 模块还包含 dumps() 函数返回 pickle 数据的字符串表示形式。
>>> from pickle import dump >>> dct = {"name":"Ravi", "age":23, "Gender":"M","marks":75} >>> dctstring = dumps(dct) >>> dctstring b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x04\x00\x00\x00Raviq\x02X\x03\x00\x00\x00ageq\x03K\x17X\x06\x00\x00\x00Genderq\x04X\x01\x00\x00\x00Mq\x05X\x05\x00\x00\x00marksq\x06KKu.'
使用 loads() 函数解开字符串并获取原始字典对象。
>>> from pickle import load >>> dct = loads(dctstring) >>> dct {'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75}
pickle 模块还定义了 Pickler 和 Unpickler 类。Pickler 类将 pickle 数据写入文件。 Unpickler 类从文件中读取二进制数据并构造 Python 对象
写入 Python 对象的 pickle 数据
from pickle import pickler f = open("data.txt","wb") dct = {'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75} Pickler(f).dump(dct) f.close()
通过 unpickling 二进制文件读回数据
from pickle import Unpickler f = open("data.txt","rb") dct = Unpickler(f).load() print (dct) f.close()
所有 Python 标准数据类型的对象都是可 picklable 的。此外,自定义类的对象也可以 pickle 和 unpickled。
from pickle import * class person: def __init__(self): self.name = "XYZ" self.age = 22 def show(self): print ("name:", self.name, "age:", self.age) p1 = person() f = open("data.txt","wb") dump(p1,f) f.close() print ("unpickled") f = open("data.txt","rb") p1 = load(f) p1.show()
Python 库还具有 marshal 模块,用于 Python 对象的内部序列化。