pickle和cPickle——python对象序列化

pickle和cPickle——python对象序列化

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>

Python有一个更原始的模块来支持序列化——marshal ,通常情况下pickle模块的性能总是比marshal模块要好,marshal的存在主要是为了支持Python的.pyc文件。

关于pyc文件不做详细介绍,这里只需知道Python的原始代码在运行前都会被先编译成字节码,并把编译的结果保存到一个一个的PyCodeObject中,pyc 文件即是把PyCodeObject从内存中以marshal格式保存到文件后的结果。


数据流格式:

pickle生成的数据流格式是Python独有的,它的优点是在被外部标准引用时是无限制的,但是对于非Python的应用无法解析pickle产生的数据流。

默认情况下,pickle生成的数据流格式使用可打印的ASCII码,对于程序员来说具有易读性,我们只需要打开存储的txt文件就能容易的理解生成的数据流,看一下上面代码中wang.txt中的内容:

c__main__
Foo
p1

很容易理解。目前在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>

可以被pickle的数据类型:

  • NoneTrue, and False
  • integers, long integers, floating point numbers, complex numbers
  • normal and Unicode strings
  • tuples, lists, sets, and dictionaries containing only picklable objects
  • functions defined at the top level of a module
  • built-in functions defined at the top level of a module
  • classes that are defined at the top level of a module
  • instances of such classes whose __dict__ or the result of calling __getstate__() is picklable (see section The pickle protocol for details).




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值