Python 模块 Pickle

Python 模块 Pickle

pickle 模块的目的是对象的序列化(Object serialization)。

pickle 模块实现了一个算法,能把任何一个对象转变为一串字节流,这个过程就叫对象的序列化

(serializing the object)。生成的字节流可以传输和保存,还能重新生成一个对象。

当解析一个未知的字节流时,可能是危险的,因为它可能是任何代码。尤其是跨进程通信的程序,需要验证这种安全性,例如可以使用 hmac 模块为数据源进行签名,然后反序列化为对象之前,首先验证这个签名是否正确。

编码和解码数据 Encoding and Decoding


dumps() 方法可以把 Python 的一个内置数据类型的数据编码为字节流。

Python 模块 Pickle

执行:

Python 模块 Pickle

dumps() 方法返回的是一串字节流,它可以写进一个文件(File),套接字(Socket)和管道

(Pipe)等等。又可以重新生成一个对象。

Python 模块 Pickle

执行:

Python 模块 Pickle

可以看到,使用 loads() 函数从字节流生成的对象和之前的一样。

写入文件流(file-like streams)


除了方法 dumps() 和 loads() 外,还可以直接将对象写入到一个类文件流(file-like streams)中。然后还可以从类文件流中读取出来,可多次写入和读取。

使用的方法是 dump() 和 load() ,和上面的方法很像,少了个字母 s。

Python 模块 Pickle

执行:

Python 模块 Pickle

这个例子,首先使用 io 模块生成了一个二进制流 f,然后使用 dump() 方法分别把2个 A 对象写入到流 f 中。

然后从被写入的流中使用函数 getvalue() 获取值,构建一个输入流 f_input,用一个 while 无限循环分别使用 load() 方法从输入流加载对象,直到2个对象加载完成后,触发异常

EOFError 退出。

pickle 模块常用在进程间通信(inter-process communication)的应用,例如使用 os.fork() 和 os.pipe() 生成的进程和管道,从一个进程或管道读取数据,然后流向另一个

进程或管道。别忘了 dump() 之后,一定要执行 flush() 方法,把数据流推送给对方。

不可序列化的对象


不是所有的对象都是可以 pickle 的,例如套接字(Sockets)、文件描述符(file handles)、数据库连接(database connections)或者其他对象依赖于操作系统或者其他进程的。

这种不能 pickle 的对象可以定义 __getstate__() 和 __setstate__() 方法。

__getstate__() 在序列化的时候调用,必须返回一个可 pickle 的对象记录自身的状态,可以是自定义的对象或者是内置的数据类型如字典。

__setstate__() 方法是在从 pickle 数据反序列化时调用的。参数是 __getstate__() 返回的数据类型值。

Python 模块 Pickle

执行:

Python 模块 Pickle

这个例子中,序列化的时候,调用 __getstate__() 方法返回一个字典对象记录自身的状态。反序列化时,把值传入了 __setstate__() 方法。


分享到:


相關文章: