一、pickle
pickle模块用来实现python对象的序列化和反序列化。通常地pickle将python对象序列化为二进制流或文件。
python对象与文件之间的序列化和反序列化:
代码如下:
pickle.dump()
pickle.load()
代码如下:
pickle.dumps()
pickle.loads()
注意:对于函数或类的序列化是以名字来识别的,所以需要import相应的module。
二、pickle的运行过程
在大部分情况下,要是的对象picklable,我们不需要额外的代码。默认地pickle将智能地检查类和实例的属性,当一个类实例反序列化的时候,它的__init__()方法通常不被调用。而是首先创建一个未初始化的实例,然后再回复存储的属性。
但是可以通过实现下列的方法来修改默认的行为:
代码如下:
object.__getstate__() :默认地序列化对象的__dict__,但是如果你实现了__getstate__(),则__getstate__()函数返回的值将被序列化。
object.__setstate__(state) :如果类型实现了此方法,则在反序列化的时候,此方法用来恢复对象的属性。
object.__getnewargs__() : 如果实例构造的时候(__new__())需要参数,则需要实现此函数。
有的时候为了效率,或上面的3个函数不能满足需求时,需要实现__reduce__()函数。
三、实例
代码如下:
import pickle
# An arbitrary collection of objects supported by pickle.
data = {
'a': [1, 2.0, 3, 4 6j],
'b': ("character string", b"byte string"),
'c': set([None, True, False])
}
with open('data.pickle', 'wb') as f:
# Pickle the 'data' dictionary using the highest protocol available.
pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)
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(str(data))
四、修改picklable类型的默认行为
代码如下:
class TextReader:
"""Print and number lines in a text file."""
def __init__(self, filename):
self.filename = filename
self.file = open(filename)
self.lineno = 0
def readline(self):
self.lineno = 1
line = self.file.readline()
if not line:
return None
if line.endswith('n'):
line = line[:-1]
return "%i: %s" % (self.lineno, line)
def __getstate__(self):
# 从 self.__dict__ 复制对象的状态,其中包含
# 我们所有的实例属性。始终使用 dict.copy()
# 避免修改原始状态的方法。
state = self.__dict__.copy()
# 删除不可picklable 的条目。
del state['文件']
返回状态
def __setstate__(self, state):
# 恢复实例属性(即文件名和行号)。
self.__dict__.update(状态)
# 恢复之前打开的文件的状态。为此,我们需要
# 重新打开它并从中读取,直到恢复行数。
file = open(self.文件名)
对于 _ 在范围内(self.lineno):
file.readline()
# 最后,保存文件。
self.file = 文件
reader = TextReader("hello.txt")
print(reader.readline())
print(reader.readline())
s = pickle.dumps(reader)
#打印
new_reader = pickle.loads(s)
print(new_reader.readline())
# 输出为
#1:你好
#2:你好吗
#3:再见