Python 序列化
术语”对象序列化”指的是将对象的状态转换为字节流的过程。一旦创建,这个字节流可以进一步存储在文件中或通过套接字传输等方式。另一方面,将字节流重新转换为对象的过程称为反序列化。
Python对于序列化和反序列化的术语分别为pickling和unpickling。Python标准库中提供的pickle模块提供了序列化(dump()和dumps())和反序列化(load()和loads())的函数。
pickle模块使用非常特定于Python的数据格式。因此,非Python编写的程序可能无法正确反序列化编码(pickled)数据。此外,从未经验证的源码解析数据被认为是不安全的。
Pickle协议
协议是构建和拆构Python对象与二进制数据之间的约定。目前,pickle模块定义了5种不同的协议,如下所示:
序号 | 协议及描述 |
---|---|
1 | 协议版本0 最初的“可读”的协议,向后兼容较早的版本。 |
2 | 协议版本1 旧的二进制格式,也与较早版本的Python兼容。 |
3 | 协议版本2 在Python 2.3中引入,为新式类提供高效的数据序列化。 |
4 | 协议版本3 在Python 3.0中新增。当需要与其他Python 3版本兼容时推荐使用。 |
5 | 协议版本4 在Python 3.4中添加。支持非常大的对象。 |
要知道您的Python安装的最高和默认协议版本,请使用 pickle 模块中定义的以下常量。
>>> import pickle
>>> pickle.HIGHEST_PROTOCOL
4
>>> pickle.DEFAULT_PROTOCOL
3
dump() 和 load() 函数是 pickle 模块用于执行 Python 数据的序列化和反序列化。dump() 函数将序列化的对象写入文件,load() 函数从文件中反序列化数据为 Python 对象。
dump() 和 load()
以下程序将一个字典对象序列化为一个二进制文件。
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}
dumps() 和 loads()
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)
print (dct)
它将产生以下 输出 –
{'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75}
选取器类
pickle模块还定义了选取器(Pickler)和非选取器(Unpickler)类。选取器类将pickle数据写入文件。非选取器类从文件中读取二进制数据并构建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()
Unpickler类
通过反序列化二进制文件来读取数据 –
from pickle import Unpickler
f=open("data.txt","rb")
dct=Unpickler(f).load()
print (dct)
f.close()
所有的Python标准数据类型的对象都可以进行pickling。此外,自定义类的对象也可以被pickle和unpickle。
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对象进行内部序列化。