资讯专栏INFORMATION COLUMN

pickle和cPickle:Python对象的序列化(上)

Sanchi / 2700人阅读

摘要:使用来创建一个表示该对象值的字符串。数据被序列化以后,你可以将它们写入文件套接字管道等等中。如果你使用管道或者套接字,在通过连至另一端的连接倾倒所有对象推送数据之后,别忘了冲洗。

目的: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)。

pythontry:
   import cPickle as pickle
except:
   import pickle
编码和解码

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

pythontry:
    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$ 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)而构造一个具有相同值得新对象。

pythontry:
    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$ 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)的转化函数。可以往一个流中写对个对象,然后从流中把它们读取出来,此过程不需要预先写入的对象有几个、它们多大。

pythontry:
    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$ 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 的前半部分

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/45327.html

相关文章

  • Python 对象列化——pickle and cPickle

    摘要:对象序列化从这篇文章粗略翻译的模块可以实现任意的对象转换为一系列字节即序列化对象的算法。的文档明确的表明它不提供安全保证。而利用则可以控制序列化的细节。 Python 对象序列化——pickle and cPickle 从这篇文章粗略翻译的pickle and cPickle pickle模块可以实现任意的Python对象转换为一系列字节(即序列化对象)的算法。这些字节流可以 被...

    Taonce 评论0 收藏0
  • picklecPicklePython对象列化(下)

    摘要:重构对象的问题当与你自己的类一起工作时,你必须保证类被腌渍出现在读取的进程的命名空间中。因为使用值而不能被腌渍的类,可以定义和来返回状态的一个子集,才能被腌渍。腌渍和反腌渍该图来创建一个结点集合。 承接上文 pickle和cPickle:Python对象的序列化(上) 。 重构对象的问题 当与你自己的类一起工作时,你必须保证类被腌渍出现在读取pickle的进程的命名空间中。...

    LeviDing 评论0 收藏0
  • python标准库学习之pickle模块

    摘要:利用标准库中的的模块可以将对象转换为一种可以传输或存储的格式。主要方法模块中有两个主要函数,它们是和。具体语法为返回一个字符串,而不是存入文件中。该方法用于反序列化,即将序列化的对象重新恢复成对象。除此之外,这两个模块的接口是几乎完全相同。 对象存在于程序运行时的内存中,当程序不再运行时或断电关机时,这些对象便不再存在。我现在想把对象保存下来,方便以后使用,这就是持久化技术。利用 py...

    宠来也 评论0 收藏0
  • Python列化安全问题

    摘要:反序列化安全问题一这一段时间使用做开发,使用了存储,阅读了源码,发现在存储到过程中,利用了模块进行序列化以及反序列化正好根据该样例学习一波反序列化相关的安全问题,不足之处请各位表哥指出。 Python 反序列化安全问题(一) 这一段时间使用flask做web开发,使用了redis存储session,阅读了flask_session源码,发现在存储session到redis过程中,利用了...

    Amos 评论0 收藏0
  • Python基础之(十一)数据存储

    摘要:默认为或者说,是以格式保存对象如果设置为或者,则以压缩的二进制格式保存对象。但是,要小心坑试图增加一个坑就在这里当试图修改一个已有键的值时没有报错,但是并没有修改成功。要填平这个坑,需要这样做多一个参数没有坑了还用循环一下 pickle pickle是标准库中的一个模块,在Python 2中还有一个cpickle,两者的区别就是后者更快。所以,下面操作中,不管是用import pick...

    Songlcy 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<