Python 对象序列化 (Pickle)

pythonprogrammingserver side programming更新于 2023/12/13 7:11:00

术语"对象序列化"是指将对象的状态转换为字节流的过程。创建后,此字节流可以进一步存储在文件中或通过套接字等传输。另一方面,从字节流重建对象称为反序列化。

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 对象的内部序列化。


相关文章