1 前言
在“通过简单示例来理解什么是机器学习”这篇文章里提到了pickle库的使用,本文来做进一步的阐述。
pickle是python语言的一个标准模块,安装python后已包含pickle库,不需要单独再安装。
pickle模块实现了基本的数据序列化和反序列化。通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储;通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。
在官方的介绍中,序列化操作的英文描述有好几个单词,如"serializing", "pickling", "serialization", "marshalling" 或者"flattening"等,它们都代表的是序列化的意思。相应的,反序列化操作的英文单词也有好多个,如"de-serializing", "unpickling", "deserailization"等。为了避免混淆,一般用"pickling"/"unpickling", 或者"serialization"/"deserailization"。
pickle
模块是以二进制的形式序列化后保存到文件中(保存文件的后缀为".pkl"),不能直接打开进行预览。而python的另一个序列化标准模块json
,则是human-readable的,可以直接打开查看(例如在notepad++中查看)。
pickle模块有两类主要的接口,即序列化和反序列化。
其中序列化操作包括:
pickle.dump()
Pickler(file, protocol).dump(obj)
反序列化操作包括:
pickle.load()
Unpickler(file).load()
2 序列化操作
2.1 序列化方法pickle.dump()
序列化的方法为 pickle.dump()
,该方法的相关参数如下:
pickle.dump(obj, file, protocol=None,*,fix_imports=True)
该方法实现的是将序列化后的对象obj以二进制形式写入文件file中,进行保存。它的功能等同于 Pickler(file, protocol).dump(obj)
。
关于参数file,有一点需要注意,必须是以二进制的形式进行操作(写入)。
参考前文的案例如下:
import pickle
with open('svm_model_iris.pkl', 'wb') as f:
pickle.dump(svm_classifier, f)
file为'svm_model_iris.pkl',并且以二进制的形式('wb')写入。
关于参数protocol,一共有5中不同的类型,即(0,1,2,3,4)。(0,1,2)对应的是python早期的版本,(3,4)则是在python3之后的版本。
此外,参数可选 pickle.HIGHEST_PROTOCOL和pickle.DEFAULT_PROTOCOL。当前,python3.5版本中,pickle.HIGHEST_PROTOCOL的值为4,pickle.DEFAULT_PROTOCOL的值为3。当protocol参数为负数时,表示选择的参数是pickle.HIGHEST_PROTOCOL。
关于参数protocol,官方的详细介绍如下:
2.2 序列化方法pickle.dumps()
pickle.dumps()
方法的参数如下:
pickle.dumps(obj, protocol=None,*,fix_imports=True)
pickle.dumps()
方法跟pickle.dump()
方法的区别在于,pickle.dumps()
方法不需要写入文件中,它是直接返回一个序列化的bytes对象。
2.3 序列化方法Pickler(file, protocol).dump(obj)
pickle模块提供了序列化的面向对象的类方法,即 class pickle.Pickler(file, protocol=None,*,fix_imports=True)
,Pickler类有dump()方法。
Pickler(file, protocol).dump(obj) 实现的功能跟 pickle.dump() 是一样的。
关于Pickler类的其他method,请参考官方API。
3 反序列化操作
3.1 反序列化方法pickle.load()
序列化的方法为 pickle.load()
,该方法的相关参数如下:
pickle.load(file, *,fix_imports=True, encoding="ASCII". errors="strict")
该方法实现的是将序列化的对象从文件file中读取出来。它的功能等同于 Unpickler(file).load()
。
关于参数file,有一点需要注意,必须是以二进制的形式进行操作(读取)。
参考前文的案例如下:
import pickle
with open('svm_model_iris.pkl', 'rb') as f:
model = pickle.load(f)
file为'svm_model_iris.pkl',并且以二进制的形式('rb')读取。
读取的时候,参数protocol是自动选择的,load()方法中没有这个参数。
3.2 反序列化方法pickle.loads()
pickle.loads()
方法的参数如下:
pickle.loads(bytes_object, *,fix_imports=True, encoding="ASCII". errors="strict")
pickle.loads()
方法跟pickle.load()
方法的区别在于,pickle.loads()
方法是直接从bytes对象中读取序列化的信息,而非从文件中读取。
3.3 反序列化方法Unpickler(file).load()
pickle模块提供了反序列化的面向对象的类方法,即 class pickle.Unpickler(file, *,fix_imports=True, encoding="ASCII". errors="strict")
,Pickler类有load()方法。
Unpickler(file).load() 实现的功能跟 pickle.load() 是一样的。
关于Unpickler类的其他method,请参考官方API。
4 那些类型可以进行序列化和反序列化操作
官方文档是这么介绍的,这里我就不进一步描述了。
写在后面
pickle模块还是比较实用的,当然,关于pickle模块,其实还有许多的信息可以去了解,想了解更多信息的童鞋,建议可以阅读下python官方的API文档(library文件)。
由于个人精力有限,简书上文章更新较慢,实在抱歉。欢迎关注微信公众号(ID:PyDataRoad)