什么是pickle?
学习《深度学习》鱼书的源码时,刚看到加载mnist数据集所用到的mnist.pkl文件,理所当然的以为pkg这样的package安装包文件。奇怪安装包为何被包含在代码目录中,结果发现
init_mnist函数还要加载它。
我们来看看这个神秘的mnist.pkl文件,打开资源管理器,发现这个文件竟然有53M
使用EditPlus打开,乱码,二进制的。
回归正题,什么是pickle?
pickle提供了一个简单的持久化功能。可以将对象以文件的形式存放在磁盘上。
pickle模块只能在python中使用,python中几乎所有的数据类型(列表,字典,集合,类等)都可以用pickle来序列化,
pickle序列化后的数据,可读性差,人一般无法识别。
pickle序列化的函数如下:
pickle.dump(obj, file[, protocol]) #序列化对象obj,并将结果数据流写入到文件对象file中
param:
obj, 输入对象,包含几乎所有的python数据类型(列表,字典,集合,类等)
file, 表示保存到的类文件对象; 注意:file必须有write()接口,file可以是一个以'w'
打开的文件或者是一个StringIO对象,也可以是任何可以实现write()接口的对象。
protocol,序列化模式
0:默认值,ASCII协议,表示以文本的形式序列化
1:二进制的形式序列化(老式的二进制协议)
2:二进制的形式序列化(新的二进制协议)
3/4/-1:python3中指定的协议,目的是让python2.x无法解析
与之对应的是反序列化对象函数:
pickle.load(file) #反序列化对象, 将文件中的数据解析为一个Python对象
#注意:在load(file)的时候,要让python能够找到类的定义,否则会报错
#file中有read()接口和readline()接口
其它函数:
pickle.dumps(obj) #以字节对象形式返回封装的对象,不需要写入文件中
pickle.loads(bytes_object) #从字节对象中读取被封装的对象,并返回
pickle模块可能出现三种异常:
1. PickleError:封装和拆封时出现的异常类,继承自Exception
2. PicklingError: 遇到不可封装的对象时出现的异常,继承自PickleError
3. UnPicklingError: 拆封对象过程中出现的异常,继承自PickleError
应用举例:回到加载mnist数据集的使用上:
def init_mnist():
download_mnist()
dataset = _convert_numpy()
print("Creating pickle file ...")
with open(save_file, 'wb') as f: //f为可用'wb'写入的二进制文件
pickle.dump(dataset, f, -1) //protocol为-1,python3中指定的协议,默认为3,当<0时,值为4
print("Done!")
if not os.path.exists(save_file):
init_mnist()
with open(save_file, 'rb') as f: //f为可用'rb'打开的二进制文件,'r'仅能打开文本文件
dataset = pickle.load(f)