pickle和cPickle:Python对象的序列化(上)
admin
2023-07-31 00:45:44
0

目的:Python对象序列化

可用性:pickle至少1.4版本,cPickle 1.5版本以上


pickle模块实现了一种算法,将任意一个Python对象转化成一系列字节(byets)。此过程也调用了serializing对象。代表对象的字节流之后可以被传输或存储,再重构后创建一个拥有相同特征(the same characteristics)的新的对象。

cPickle使用C而不是Python,实现了相同的算法。这比Python实现要快好几倍,但是它不允许用户从Pickle派生子类。如果子类对你的使用来说无关紧要,那么cPickle是个更好的选择。

警告:本文档直接说明,pickle不提供安全保证。如果你在多线程通信(inter-process communication)或者数据存储或存储数据中使用pickle,一定要小心。请勿信任你不能确定为安全的数据。

导入

如平常一样,尝试导入cPickle,给它赋予一个别名“pickle”。如果因为某些原因导入失败,退而求其次到Python的原生(native)实现pickle模块。如果cPickle可用,能给你提供一个更快速的执行,否则只能是轻便的执行(the portable implementation)。

12345 try:   import cPickle as pickleexcept:   import pickle 

编码和解码

第一个例子将一种数据结构编码成一个字符串,然后把该字符串打印至控制台。使用一种包含所有原生类型(native types)的数据结构。任何类型的实例都可被腌渍(pickled,译者注:模块名称pickle的中文含义为腌菜),在稍后的例子中会演示。使用pickle.dumps()来创建一个表示该对象值的字符串。

12345678910111213 try:    import cPickle as pickleexcept:    import pickleimport pprint data = [ { \’a\’:\’A\’, \’b\’:2, \’c\’:3.0 } ]print \’DATA:\’,pprint.pprint(data) data_string = pickle.dumps(data)print \’PICKLE:\’, data_string 

pickle默认仅由ASCII字符组成。也可以使用更高效的二进制格式(binary format),只是因为在打印的时候更易于理解,本页的所有例子都使用ASCII输出。

12345678910111213 $ python pickle_string.py DATA:[{\’a\’: \’A\’, \’b\’: 2, \’c\’: 3.0}]PICKLE: (lp1(dp2S\’a\’S\’A\’sS\’c\’F3sS\’b\’I2sa. 

数据被序列化以后,你可以将它们写入文件、套接字、管道等等中。之后你也可以从文件中读取出来、将它反腌渍(unpickled)而构造一个具有相同值得新对象。

12345678910111213141516171819 try:    import cPickle as pickleexcept:    import pickleimport pprint data1 = [ { \’a\’:\’A\’, \’b\’:2, \’c\’:3.0 } ]print \’BEFORE:\’,pprint.pprint(data1) data1_string = pickle.dumps(data1) data2 = pickle.loads(data1_string)print \’AFTER:\’,pprint.pprint(data2) print \’SAME?:\’, (data1 is data2)print \’EQUAL?:\’, (data1 == data2) 

如你所见,这个新构造的对象与原对象相同,但并非同一对象。这不足为奇。

1234567 $ python pickle_unpickle.py BEFORE:[{\’a\’: \’A\’, \’b\’: 2, \’c\’: 3.0}]AFTER:[{\’a\’: \’A\’, \’b\’: 2, \’c\’: 3.0}]SAME?: FalseEQUAL?: True 

与流一起工作

dumps()loads()外,pickle还提供一对用在类文件流(file-like streams)的转化函数。可以往一个流中写对个对象,然后从流中把它们读取出来,此过程不需要预先写入的对象有几个、它们多大。

123456789101112131415161718192021222324252627282930313233343536373839404142 try:    import cPickle as pickleexcept:    import pickleimport pprintfrom StringIO import StringIO class SimpleObject(object):     def __init__(self, name):        self.name = name        l = list(name)        l.reverse()        self.name_backwards = \’\’.join(l)        return data = []data.append(SimpleObject(\’pickle\’))data.append(SimpleObject(\’cPickle\’))data.append(SimpleObject(\’last\’)) # 使用StringIO模拟一个文件out_s = StringIO() # 写入该流for o in data:    print \’WRITING: %s (%s)\’ % (o.name, o.name_backwards)    pickle.dump(o, out_s)    out_s.flush() # 建立一个可读流in_s = StringIO(out_s.getvalue()) # 读数据while True:    try:        o = pickle.load(in_s)    except EOFError:        break    else:        print \’READ: %s (%s)\’ % (o.name, o.name_backwards) 

这个例子使用SringIO缓存器(buffer)模拟流,所以在建立可读流的时候我们玩了一把。一个简单数据库的格式化也可以使用pickles来存储对象,只是shelve与之工作更加简便。

123456789 $ python pickle_stream.py WRITING: pickle (elkcip)WRITING: cPickle (elkciPc)WRITING: last (tsal)READ: pickle (elkcip)READ: cPickle (elkciPc)READ: last (tsal) 

除了存储数据,pickles在进程间通信(inter-process communication)中也非常称手。例如,使用os.fork()os.pipe()可以创立工作者进程(worker processes),从一个管道(pipe)读取作业指令(job instruction)然后将结果写入另一个管道。管理工作者池(worker pool)和将作业送入、接受响应(response)的核心代码可被重用,因为作业和响应并不属于某个特定类中。如果你使用管道或者套接字(sockets),在通过连至另一端(end)的连接倾倒(dumps)所有对象、推送数据之后,别忘了冲洗(flush)。如果你想写自己的工作者池管理器,请看multiprocessing

Next–>


相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
python清除字符串里非数字... 本文实例讲述了python清除字符串里非数字字符的方法。分享给大家供大家参考。具体如下: impor...