pickle(模型存储取出)

在机器学习中,我们常常需要把训练好的模型存储起来,这样在进行决策时直接将模型读出,而不需要重新训练模型,这样就大大节约了时间。Python提供的pickle模块就很好地解决了这个问题,它可以序列化对象并保存到磁盘中,并在需要的时候读取出来,任何对象都可以执行序列化操作。

5种协议

  • Protocol version 0 是最原始一种协议,它向后与以前的Python版本兼容。
  • Protocol version 1 是一种老的二进制格式,它也兼容以前版本的Python。
  • Protocol version 2 是在 Python2.3 中被引入的。它提供了对新类型new-style class更加高效的pickling。
  • Protocol version 3 是在 Python3.0 中加入的。它明确的支持了字节对象bytes objects的pickling,且不能被Python2.x unpickling。这个协议就是默认的协议,也是在Python3的其他版本中推荐的协议。
  • Protocol version 4 是在Python3.4中被加入的。它增加了对超大对象的支持,且支持pickling的对象类型也更多。

Pickle模块常用的接口函数

  1. pickle.HIGHEST_PROTOCOL
    这是一个整数,表示最高可用的协议版本。这个值可以作为参数protocol传给函数dump()和dumps()以及Pickler构造器。
  2. pickle.DEFAULT_PROTOCOL
    这是一个整数,表示用来pickling的默认协议版本。可能比3. 3. pickle.HIGHEST_PROTOCOL小。目前默认的协议版本是3,协议3是专门为Python3设计的一种新的协议。
  3. pickle.dump(obj, file, protocol=None, *, fix_imports=True)
    pickle.dump(obj, file, [,protocol])
    将一个对象序列化,并将其写入文件对象中。这等价于函数Pickler(file, protocol).dump(obj)。
  4. protocol参数是可选的,是一个整数,用来表示用到的协议版本。支持的协议为0到HIGHEST_PROTOCOL。如果没有指定,就是默认的DEFAULT_PROTOCOL。如果传入的是负数,那么HIGHEST_PROTOCOL就被指定为协议版本。
    file参数必须有一个write()方法,该方法接收一个单字节参数。
  5. pickle.dumps(obj, protocol=None, *, fix_imports=True)
    返回一个序列化后的对象,作为字节对象bytes objects,而不是将其写入文件中。
    pickle.dumps(obj[, protocol])
  • 函数的功能:将obj对象序列化为string形式,而不是存入文件中。
  • obj:想要序列化的obj对象。
  • protocal:如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。
  1. pickle.load(file, *, fix_imports=True, encoding=“ASCII”, errors=“strict”)
    pickle.load(file)
    从文件对象中读取一个序列化后的对象并将其解序列化成原来的层级结构。这等价于函数Unpickler(file).load()。
    file参数必须有两个方法:read()方法接收一个整数参数和一个readlines()方法不要求参数。两个方法都应该返回字节。
  2. pickle.loads(bytes_object, *, fix_imports=True, encoding=“ASCII”, errors=“strict”)
    pickle.loads(string)
    — 函数的功能:从string中读出序列化前的obj对象。
    从字节对象bytes objects读取一个被序列化的对象,返回解序列化后的对象。

pickle模块衍生出两个类

  1. class pickle.Pickler(file, protocol=None, *, fix_imports=True)
  2. class pickle.Unpickler(file, *, fix_imports=True, encoding=“ASCII”, errors=“strict”)
    这两个类也有一些方法,跟上面的方法等价,例如Pickler类的dump()方法、Unpickler类的load()方法。

什么东西可以被序列化

None, True, 和 False
整数、浮点数和复数
字符串、字节和字节数组
元组、列表、集合和仅包括可序列化对象的字典
定义在一个模块上层的函数
定义在一个模块上层的内建函数
定义在一个模块上层的类
一些类的实例,这些类包括其__dict__或调用__getstate__()的结果是可序列化的。

JSON和pickle模块的区别

1、JSON只能处理基本数据类型。pickle能处理所有Python的数据类型。
2、JSON用于各种语言之间的字符转换。pickle用于Python程序对象的持久化或者Python程序间对象网络传输,但不同版本的Python序列化可能还有差异。

import pickle

#支持序列化的字典
data = {
    'a': [1, 2.0, 3, 4+6j],
    'b': ("character string", b"byte string"),
    'c': {None, True, False}
}

with open('data.pickle', 'wb') as f:
    # Pickle the 'data' dictionary using the highest protocol available.
    # 用最高协议版本序列化data字典,将其写入文件"data.pickle"中
    pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)


# 经过上面的代码,已经在本地磁盘中写入了一个文件"data.pickle",现在我们将其读入,并将其解序列化
import pickle

with open('data.pickle', 'rb') as f:
    # The protocol version used is detected automatically, so we do not
    # have to specify it.
    data = pickle.load(f)
print(data)

以上一段代码的输出内容如下,可见经过解序列化之后的结构与原来的结构保持一致
{'a': [1, 2.0, 3, (4+6j)], 'b': ('character string', b'byte string'), 'c': {False, None, True}}

【注】 dump() 与 load() 相比 dumps() 和 loads() 还有另一种能力:dump()函数能一个接着一个地将几个对象序列化存储到同一个文件中,随后调用load()来以同样的顺序反序列化读出这些对象。

 【代码示例】
import pickle  
dataList = [[1, 1, 'yes'],  
            [1, 1, 'yes'],  
            [1, 0, 'no'],  
            [0, 1, 'no'],  
            [0, 1, 'no']]  
dataDic = { 0: [1, 2, 3, 4],  
            1: ('a', 'b'),  
            2: {'c':'yes','d':'no'}}  
  
#使用dump()将数据序列化到文件中  
fw = open('dataFile.txt','wb')  
# Pickle the list using the highest protocol available.  
pickle.dump(dataList, fw, -1)  
# Pickle dictionary using protocol 0.  
pickle.dump(dataDic, fw)  
fw.close()  
  
#使用load()将数据从文件中序列化读出  
fr = open('dataFile.txt','rb')  
data1 = pickle.load(fr)  
print(data1)  
data2 = pickle.load(fr)  
print(data2)  
fr.close()  
  
#使用dumps()和loads()举例  
p = pickle.dumps(dataList)  
print( pickle.loads(p) )  
p = pickle.dumps(dataDic)  
print( pickle.loads(p) )  

结果为:
[[1, 1, ‘yes’], [1, 1, ‘yes’], [1, 0, ‘no’], [0, 1, ‘no’], [0, 1, ‘no’]]
{0: [1, 2, 3, 4], 1: (‘a’, ‘b’), 2: {‘c’: ‘yes’, ‘d’: ‘no’}}
[[1, 1, ‘yes’], [1, 1, ‘yes’], [1, 0, ‘no’], [0, 1, ‘no’], [0, 1, ‘no’]]
{0: [1, 2, 3, 4], 1: (‘a’, ‘b’), 2: {‘c’: ‘yes’, ‘d’: ‘no’}}

你可能感兴趣的:(python基础)