【摘要】本篇博文简析了何为pickle模块,为什么要用pickle模块以及如何使用。
python的pickle模块实现了python的所有数据序列和反序列化。与JSON不同的是pickle不是用于多种语言间的数据传输,它仅作为python对象的持久化或者python程序间进行互相传输对象的方法,因此它支持了python所有的数据类型。
在讲JSON模块的时候,我们就讲了序列化与反序列化。那么到底什么是序列化呢?
序列化是什么?
序列化是指将对象、数据结构的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
序列化的作用是什么?
我们编写的程序,会涉及到各种各样的对象、数据结构,它们通常是以变量的形式在内存中存在着。当程序运行结束后,这些变量也就会被清理。但我们有时希望能够在下一次编写程序时恢复上一次的某个对象(如机器学习中的到结果,需要程序运行较长时间,多次运行时间成本太大),这就需要我们将变量进行持久化的存储。一种方式是利用文件读写的方式将变量转化为某种形式的字符串写入文件内,但需要自己控制存储格式显得十分笨拙。更好的方式是通过序列化的方式将变量持久化至本地。
我们知道不是所有的python对象都可以转换为JSON对象,例如集合、datetime对象等。
请看下面的代码:
import json
nums = range(1, 10)
print(type(nums))
#json不能成功的序列化
json_nums = json.dumps(nums)
print(json_nums)
就会出现如下报错:
json不能将range对象序列化。这个时候,就需要用到pickle模块了,因为这个模块支持所有的python数据类型。
pickle模块序列化
函数 | 描述 |
---|---|
pickle.dumps( ) | 将python对象序列化成pickle的bytes类型数据 |
pickle.dump( ) | 将python对象序列化存入已经打开的文件中 |
【注】
pickle.dump(obj, file,[protocol])
序列化对象,并将结果数据流写入到文件对象中。参数protocol是序列化模式,默认值为0,表示以文本的形式序列化。protocol的值还可以是1或2,表示以二进制的形式序列化。
针对上面json无法序列化的range对象,我们看一下pickle模块是否可以序列化?
import pickle
nums = range(1, 10)
print(type(nums))
pickle_nums = pickle.dumps(nums)
print(pickle_nums)
print("序列化:", type(pickle_nums))
很明显,pickle模块可以序列化range对象。
再看看dump()方法
with open ('doc/user.txt','wb') as f:
pickle_numsNew = pickle.dump(nums,f)
特别要注意,以二进制的权限打开文件,因为序列化后的数据是bytes类型而不是string类型。如果不加b,会报如下错误:
打开文件,可以看到序列化后的内容:
pickle模块反序列化
函数 | 描述 |
---|---|
pickle.loads( ) | 将pickle的bytes类型数据反序列化成python对象 |
pickle.load( ) | 将文件中pickle的bytes类型数据反序列化成python对象 |
unpickle_nums = pickle.loads(pickle_nums)
print(unpickle_nums)
print("反序列化:", type(unpickle_nums))
我们将上面序列化后的bytes类型反序列化为python对象
load()方法:
从上面doc/user.txt文件中反序列化其中的bytes类型:
with open ('doc/user.txt','rb') as f:
pickle_numsNew = pickle.load(f)
print(pickle_numsNew)
print(type(pickle_numsNew))
【补充】
cPickle是pickle模块的C语言编译版本,相对速度更快。
因此,读者可以这样做:
import cPickle as pickle
剩下用法是一样的。
JSON只能处理基本数据类型。pickle能处理所有Python的数据类型。
JSON用于各种语言之间的字符转换。pickle用于Python程序对象的持久化或者Python程序间对象网络传输,但不同版本的Python序列化可能还有差异。
json :
序列化(编码): python对象编码成json字符串
反序列化(解码): 将json字符串转成python对象
pickle:
序列化(编码): python对象编码成pickle的bytes类型数据
反序列化(解码): 将pickle的bytes类型数据转成python对象