加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

pickle和cPickle:Python对象的序列化

发布时间:2020-12-13 20:13:00 所属栏目:PHP教程 来源:网络整理
导读:目的:Python对象序列化 可用性:pickle最少1.4版本,cPickle 1.5版本以上 pickle 模块实现了1种算法,将任意1个Python对象转化成1系列字节(byets)。此进程也调用了 serializing 对象。代表对象的字节流以后可以被传输或存储,再重构后创建1个具有相同特点

目的:Python对象序列化
可用性:pickle最少1.4版本,cPickle 1.5版本以上


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

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

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

导入

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

try: import cPickle as pickle except: import pickle

编码和解码

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

try: import cPickle as pickle except: import pickle import pprint data = [ { 'a':'A','b':2,0)">'c':3.0 } ] print 'DATA:',pprint.pprint(data) data_string = pickle.dumps(data) print 'PICKLE:',data_string

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

$ python pickle_string.py DATA:[{'a': 'b': 'c': 3.0}] PICKLE: (lp1 (dp2 S'a' S'A' sS'c' F3 sS'b' I2 sa.

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

try: import cPickle as pickle except: import pickle import pprint data1 = [ { '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)

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

$ python pickle_unpickle.py BEFORE:[{3.0}] AFTER:[{3.0}] SAME?: False EQUAL?: True

与流1起工作

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

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摹拟1个文件 out_s = StringIO() # 写入该流 for o in data: print 'WRITING: %s (%s)' % (o.name,o.name_backwards) pickle.dump(o,out_s) out_s.flush() # 建立1个可读流 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)摹拟流,所以在建立可读流的时候我们玩了1把。1个简单数据库的格式化也能够使用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),从1个管道(pipe)读取作业指令(job instruction)然后将结果写入另外一个管道。管理工作者池(worker pool)和将作业送入、接受响应(response)的核心代码可被重用,由于作业和响应其实不属于某个特定类中。如果你使用管道或套接字(sockets),在通过连至另外一端(end)的连接倾倒(dumps)所有对象、推送数据以后,别忘了冲洗(flush)。如果你想写自己的工作者池管理器,请看multiprocessing

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读