博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
pickle和cPickle:Python对象的序列化(上)
阅读量:7097 次
发布时间:2019-06-28

本文共 3163 字,大约阅读时间需要 10 分钟。

https://segmentfault.com/a/1190000002493548 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)。 try: import cPickle as pickle except: import pickle 编码和解码 第一个例子将一种数据结构编码成一个字符串,然后把该字符串打印至控制台。使用一种包含所有原生类型(native types)的数据结构。任何类型的实例都可被腌渍(pickled,译者注:模块名称pickle的中文含义为腌菜),在稍后的例子中会演示。使用pickle.dumps()来创建一个表示该对象值的字符串。 try: import cPickle as pickle except: import pickle import 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输出。 $ python pickle_string.py DATA:[{'a': 'A', 'b': 2, 'c': 3.0}] PICKLE: (lp1 (dp2 S'a' S'A' sS'c' F3 sS'b' I2 sa. 数据被序列化以后,你可以将它们写入文件、套接字、管道等等中。之后你也可以从文件中读取出来、将它反腌渍(unpickled)而构造一个具有相同值得新对象。 try: import cPickle as pickle except: import pickle import 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) 如你所见,这个新构造的对象与原对象相同,但并非同一对象。这不足为奇。 $ python pickle_unpickle.py BEFORE:[{'a': 'A', 'b': 2, 'c': 3.0}] AFTER:[{'a': 'A', 'b': 2, 'c': 3.0}] SAME?: False EQUAL?: True 与流一起工作 除dumps()和loads()外,pickle还提供一对用在类文件流(file-like streams)的转化函数。可以往一个流中写对个对象,然后从流中把它们读取出来,此过程不需要预先写入的对象有几个、它们多大。 try: import cPickle as pickle except: import pickle import pprint from 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与之工作更加简便。 $ 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。 原文:pickle and cPickle – Python object serialization - Python Module of the Week 的前半部分

转载地址:http://fahql.baihongyu.com/

你可能感兴趣的文章
java web 答辩总结
查看>>
GUI测试含义
查看>>
javabean使用技巧
查看>>
JS/JQ综合总结
查看>>
CGAffineTransform相关函数
查看>>
字符编码与字符集区别与联系(网页/PHP文件/MYSQL数据库乱码问题)
查看>>
黑马程序员-----const和readonly的区别
查看>>
转载:基于MapXtreme的鹰眼功能
查看>>
黄聪:远程序桌面登录的.NET(C#)开发
查看>>
JMeter聚合报告(Aggregate Report)理解
查看>>
C# 多线程Thread.IsBackground=True的作用
查看>>
Oracle数据库安装问题记录
查看>>
Error:flask_sqlalchemy
查看>>
算法3-排序-简单选择排序
查看>>
poj 1743 Musical Theme (后缀数组)
查看>>
XACML学习
查看>>
Java中文乱码问题研究(二)
查看>>
easyui图标大全
查看>>
Emmet:HTML/CSS代码快速编写神器
查看>>
webpack实战
查看>>