@spiritnotes
2016-07-23T14:56:53.000000Z
字数 1513
阅读 2586
Python
DOING
Python有对应的序列化模块pickle和cplikle,pickle和cpickle一样,不同点在于前者使用python实现而后者使用c实现,表现为性能上的差别。主要功能就是使用了一种算法,将python对象转化成一系列字节,该过程调用serializing对象。生成的字符串可以再进行传输或者存储,而重构后可以创建一个拥有相同特征(the same charracteristics)的新的对象。
直接导入该模块即可使用,在正常情况下,优先导入cpickle模块,如果出现异常再导入pickle模块。
try:
import cplickle as pickle
except:
import pickle
导出使用dump和dumps,参数有模式选择,模式0和1为二进制模式,模式2为ascii字符串模式,在性能(存储空间大小和编码解码时间)上有差异。dump作用在流上,而dumps作用在字符串上。
导入使用loads和load,导入的对象和原对象一样,但非同一个对象,其内存地址会发生变化。
可以通过使用os.fork和os.pipe创建进程间通信而直接传送对象。
pickle函数主要是对实例对象(instance)的属性进行序列化,可以理解为是通过self.xxx进行赋值而产生的实例对象,而类变量、类中定义的函数等是通过代码执行产生的,这也是unpickle必须要有类定义的原因。
load的流程主要由如下几个部分组成:
当对象的数据类型不能被pickle时(套接字、文件句柄、数据库链接等),可以使用__getstate__和__setstate__来返回状态的一个子集,针对该子集进行pickle。新式类可以定义__getnewargs__,该函数应当返回被传递至类内存分配器(.__new__)。
pickle协议能够自动处理对象间的环形引用。因此使用时不需要考虑该种情况。
当使用python2.7进行pickle时如果有对象属性为函数对象,则可能会出现以下错误:
PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed
该问题是由于其不支持序列化函数,可以使用copy_reg将MethodType注册为可序列化来解决
import copy_reg
import types
def _pickle_method(m):
if m.im_self is None:
return getattr, (m.im_class, m.im_func.func_name)
else:
return getattr, (m.im_self, m.im_func.func_name)
copy_reg.pickle(types.MethodType, _pickle_method)
更多方法可以见 https://blog.tankywoo.com/2015/09/06/cant-pickle-instancemethod.html
当文件超过一定的大小后,在pickle的时候会出错,主要有如下两种错误,除了手动将对象拆分后进行多次pickle,暂时还未发现解决办法。