pickle模块引入了一个基础的但是强大的python对象序列化和反序列化的方法。(pickling and unpickling)
picking 是这样一个过程——把python对象转化为二进制流的形式,unpickling是这个的逆过程。
注意:pickle模块是不安全的,Hacker可能利用pickle模块进行恶意代码注入。对于picking过程而言并不需要担心,因为它产生的都是string,但是对于unpickling过程,unpicke一个不受信赖的string不一定是安全的,因为unpickle很可能产生无法预料的对象。所以要注意你unpickle的string的来源。
与pickle模块相近的一个模块是cPickle,正如其名它是使用c语言写的,相比之下它的速度大约是pickle模块的1000倍,然而cPickle相比pickle不支持Pickler()和Unpickler()的子类,因为在cPickle模块中只有函数并没有类的存在。cPickle模块和pickle模块在某些情况下可以互用,比如对于一个数据流(使用dump存储在文件中的数据),我们既可以使用cPickle模块的load方法也可以使用pickle模块的load方法进行读取。
<span style="font-size:14px;">>>> import cPickle >>> import pickle >>> class Foo: name = 'wang' >>> f = open('N:\\wang.txt','w') >>> cPickle.dump(Foo,f) >>> f.close() >>> f = open('N:\\wang.txt','r') >>> print pickle.load(f) __main__.Foo >>> f.close() >>> f = open('N:\\wang.txt','r') >>> print cPickle.load(f) __main__.Foo >>> f.close()</span>
关于pyc文件不做详细介绍,这里只需知道Python的原始代码在运行前都会被先编译成字节码,并把编译的结果保存到一个一个的PyCodeObject中,pyc 文件即是把PyCodeObject从内存中以marshal格式保存到文件后的结果。
数据流格式:
pickle生成的数据流格式是Python独有的,它的优点是在被外部标准引用时是无限制的,但是对于非Python的应用无法解析pickle产生的数据流。
默认情况下,pickle生成的数据流格式使用可打印的ASCII码,对于程序员来说具有易读性,我们只需要打开存储的txt文件就能容易的理解生成的数据流,看一下上面代码中wang.txt中的内容:
很容易理解。目前在pickling中有三种不同的协议:
protocol 0 :原始的ASCII协议,向后兼容
protocol 1:老的二进制格式,同样向后兼容
protocol 2:Python2.3引入,对于新式类(new-style classes)提供了更有效的pickling
Example:
<span style="font-size:14px;">import pickle data1 = {'a': [1, 2.0, 3, 4+6j], 'b': ('string', u'Unicode string'), 'c': None} selfref_list = [1, 2, 3] selfref_list.append(selfref_list) output = open('data.pkl', 'wb') # Pickle dictionary using protocol 0. pickle.dump(data1, output) # Pickle the list using the highest protocol available. pickle.dump(selfref_list, output, -1) output.close()</span>
<span style="font-size:14px;">import pprint, pickle pkl_file = open('data.pkl', 'rb') data1 = pickle.load(pkl_file) pprint.pprint(data1) data2 = pickle.load(pkl_file) pprint.pprint(data2) pkl_file.close()</span>