Python对象序列化(Pickle)

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

Python的序列化和反序列化术语分别为酸洗和反酸洗。Python标准库中提供的pickle模块提供了序列化(dump()和dumps())和反序列化(load()和loads())的功能。

pickle模块使用非常特定于Python的数据格式。因此,未使用Python编写的程序可能无法正确反序列化编码(腌制)的数据。同样,从未经身份验证的源释放数据也被认为是不安全的。

泡菜协议

协议是在Python对象与二进制数据之间进行构造和解构的约定。目前,泡菜模块定义了5种不同的协议,如下所示-

协议版本0原始的“人类可读”协议向后兼容早期版本。
协议版本1旧的二进制格式也与Python的早期版本兼容。
协议版本2Python 2.3中引入的方法可以高效地腌制新样式的类。
协议版本3在Python 3.0中添加。当需要与其他Python 3版本兼容时,建议使用此选项。
协议版本4是在Python 3.4中添加的。它增加了对非常大的对象的支持

要了解Python安装的最高和默认协议版本,请使用pickle模块中定义的以下常量

>>> import pickle
>>> pickle.HIGHEST_PROTOCOL
4
>>> pickle.DEFAULT_PROTOCOL
3

正如前面提到的dump()load()泡菜模块的功能进行封装状态Python数据。该dump()函数将腌制的对象写入文件,然后将load()数据从文件中剔除到Python对象。

在程序中将字典对象腌制为二进制文件。

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()返回腌制数据的字符串表示形式的函数。

>>> 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对象的腌制数据

from pickle import pickler
f = open("data.txt","wb")
dct = {'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75}
Pickler(f).dump(dct)
f.close()

通过解开二进制文件来回读数据

from pickle import Unpickler
f = open("data.txt","rb")
dct = Unpickler(f).load()
print (dct)
f.close()

所有Python标准数据类型的对象都是可腌制的。而且,自定义类的对象也可以被酸洗和不被酸洗。

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