一、pickle/Cpickle简介

  Python序列化的概念很简单。内存里面有一个数据结构,你希望将它保存下来,重用,或者发送给其他人。你会怎么做?这取决于你想要怎么保存,怎么重用,发送给谁。很多游戏允许你在退出的时候保存进度,然后你再次启动的时候回到上次退出的地方。(实际上,很多非游戏程序也会这么干)在这种情况下,一个捕获了当前进度的数据结构需要在你退出的时候保存到硬盘上,接着在你重新启动的时候从硬盘上加载进来。
  Python标准库提供pickle和cPickle模块。cPickle是用C编码的,在运行效率上比pickle要高,但是cPickle模块中定义的类型不能被继承(其实大多数时候,我们不需要从这些类型中继承,推荐使用cPickle)。cPickle和pickle的序列化/反序列化规则是一样的,使用pickle序列化一个对象,可以使用cPickle来反序列化。同时,这两个模块在处理自引用类型时会变得更加“聪明”,它不会无限制的递归序列化自引用对象,对于同一对象的多次引用,它只会序列化一次。

  pickle模块中的两个主要函数是dump()和load()。dump()函数接受一个数据对象和一个文件句柄作为参数,把数据对象以特定的格式保存到给定的文件中。当我们使用load()函数从文件中取出已保存的对象时,pickle知道如何恢复这些对象到它们本来的格式。
  dumps()函数执行和dump()函数相同的序列化。取代接受流对象并将序列化后的数据保存到磁盘文件,这个函数简单的返回序列化的数据。
  loads()函数执行和load()函数一样的反序列化。取代接受一个流对象并去文件读取序列化后的数据,它接受包含序列化后的数据的str对象, 直接返回的对象。
  cPickle.dump(obj, file, protocol=0):序列化对象,并将结果数据流写入到文件对象中。参数protocol是序列化模式,默认值为0,表示以文本的形式序列化。protocol的值还可以是1或2,表示以二进制的形式序列化。
      cPickle.load(file):反序列化对象。将文件中的数据解析为一个Python对象。python中可以使用pickle模块将对象转换为文件保存在磁盘上,在需要的时候再读取并还原。

二、pickle的具体用法

pickle.dump(obj,file[,protocol])

dump:是将对象持久化的方法,参数的含义分别为:

  1.obj:要持久化保存的对象,比如列表,字典或者是字符串
  2.file:一个拥有write()方法的对象,并且这个write()方法能接收一个字符串作为参数。这个对象可以是一个以写模式打开的文件对象或者一个StringIO对象,或者其他自定义的满足条件的对象
  3.protocol:这是一个可选的参数,默认为0,如果设置为1或True,则以高压缩的二进制格式保存持久化的对象,否则以ASCII格式保存。

  对象持久化后如何还原呢?使用load方法

 pickle.load(file)
  只有一个参数file,对应于上面dump方法中的file参数。这个file必须是一个拥有一个能接收一个整数为参数的read()方法以及一个不接收任何参数的readline()方法,并且这两个方法的返回值都应该是字符串。这可以是一个打开为读的文件对象、StringIO对象或其他任何满足条件的对象

三、具体实例

实例一:pickle.dump()和pickle.load()的简单应用

import pickle
obj = {'a':1,'b':2,'c':3}
pickle.dump(obj, open("tmp.txt",'w'))
obj2 = pickle.load(open("tmp.txt",'r'))
print obj2

程序执行结果:

{'a': 1, 'c': 3, 'b': 2}

实例二:将dump 第三个参数设为 True 以提高压缩比

不过实际应用中,我们可能还会有一些改进,比如用 cPickle 来代替 pickle ,前者是后者的一个 C 语言实现版本,拥有更快的速度,另外,有时在 dump 时也会将第三个参数设为 True 以提高压缩比

#_*_coding:utf-8_*_

import cPickle as pickle
import random
import os
import time
#设置循环的次数
LENGTH = 1024 * 1024 #随机生成1024 * 1024个0-255中间的整数
def main():
d = {}
a = []
for i in range(LENGTH):
a.append(random.randint(0, 255)) #将整个列表作为字典的value
d['a'] = a print "dumping..." #求字典对象存放到tmp1.dat文件中所需要的时间
#将dump的第三个参数设置为Ture,目的是提高压缩比
t1 = time.time()
pickle.dump(d, open("tmp1.dat", "wb"), True)
print "dump1: %.3fs" % (time.time() - t1) t1 = time.time()
pickle.dump(d, open("tmp2.dat", "w"))
print "dump2: %.3fs" % (time.time() - t1) #s1 s2文件的大小
s1 = os.stat("tmp1.dat").st_size
s2 = os.stat("tmp2.dat").st_size print "%d,%d,%.2f%%" %(s1,s2,100.0 * s1 / s2) print "loading....." #将字典对象加载到内存需要花费的时间
t1 = time.time()
obj1 = pickle.load(open("tmp1.dat", "rb"))
print "load1: %.3fs" % (time.time() - t1) t1 = time.time()
obj2 = pickle.load(open("tmp2.dat","r"))
print "load2: %.3fs" %(time.time() - t1) if __name__ == "__main__":
main()

程序执行结果:

dumping...
dump1: 0.106s
dump2: 0.476s
2099261,6890167,30.47%
loading.....
load1: 0.222s
load2: 0.870s

可以看到,dump 时如果指定了 protocol 为 True,压缩过后的文件的大小只有原来的文件的 30% ,同时无论在 dump 时还是 load 时所耗费的时间都比原来少。因此,一般来说,可以建议把这个值设为 True 。

实例三:pickle.dump() 和pickle.load()

  它们使用文件和类似文件的对象。这些函数的操作非常类似于我们刚才所看到的 dumps() 和 loads() ,区别在于它们还有另一种能力 — dump() 函数能一个接着一个地将几个对象转储到同一个文件。随后调用 load() 来以同样的顺序检索这些对象

import cPickle as pickle
a1 = 'apple'
b1 = {1:'one',2:'two',3:'three'}
c1 = ['free','fie','foe','fum'] with file('temp.pk1','wb') as f: pickle.dump(a1,f,True)
pickle.dump(b1,f,True)
pickle.dump(c1,f,True) with file('temp.pk1','rb') as f2:
a2 = pickle.load(f2)
print a2
b2 = pickle.load(f2)
print b2
c2 = pickle.load(f2)
print c2

程序执行结果:

apple
{1: 'one', 2: 'two', 3: 'three'}
['free', 'fie', 'foe', 'fum']

四、pickle.dumps()和pickle.loads()

  pickle 模块还提供 dumps 和 loads 两个方法,用法与上面的 dump 和 load 方法类似,只是不需要输入 file 参数,输入及输出都是字符串对象,有些场景中使用这两个方法可能更为方便。

参考文章:

http://www.cnblogs.com/evening/archive/2012/04/01/2427876.html

http://oldj.net/article/python-pickle/

python序列化pickle/cPickle的更多相关文章

  1. Python 序列化 pickle/cPickle模块

    Python 序列化 pickle/cPickle模块 2013-10-17 Posted by yeho Python序列化的概念很简单.内存里面有一个数据结构,你希望将它保存下来,重用,或者发送给 ...

  2. Python 序列化pickle/cPickle模块整理

    Python序列化的概念很简单.内存里面有一个数据结构,你希望将它保存下来,重用,或者发送给其他人.你会怎么做?这取决于你想要怎么保存,怎么重用,发送给谁.很多游戏允许你在退出的时候保存进度,然后你再 ...

  3. Python序列化-pickle和json模块

    Python的“file-like object“就是一种鸭子类型.对真正的文件对象,它有一个read()方法,返回其内容.但是,许多对象,只要有read()方法,都被视为“file-like obj ...

  4. python 序列化 pickle shelve json configparser

    1. 什么是序列化 我们把变量从内存中变成可存储或传输的过程称之为序列化. 序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上. 反过来,把变量内容从序列化的对象重新读到内存里称 ...

  5. python 序列化pickle 和 encode的区别

    我们把变量从内存中变成可存储或传输的过程称之为序列化. 序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上. 反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即un ...

  6. Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式

    Python第十四天 序列化  pickle模块  cPickle模块  JSON模块  API的两种格式 目录 Pycharm使用技巧(转载) Python第一天  安装  shell  文件 Py ...

  7. python 序列化之JSON和pickle详解

    JSON模块 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了类 ...

  8. 从watevrCTF-2019:Pickle Store中学习python之pickle序列化漏洞

    从watevrCTF-2019:Pickle Store中学习python之pickle序列化漏洞 pickle提供了一个简单的持久化功能.可以将对象以文件的形式存放在磁盘上. 其本质是Picklin ...

  9. python 序列化 json pickle

    python的pickle模块实现了基本的数据序列和反序列化.通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储:通过pickle模块的反序列化操作,我们能够从文件 ...

随机推荐

  1. Zookeeper分布式服务协调组件

    1.简介 Zookeeper是一个分布式服务协调组件,是Hadoop.Hbase.Kafka的重要组件,它是一个为分布式应用提供一致性服务的组件.   Zookeeper的目标就是封装好复杂易出错的服 ...

  2. Linux命令(持续更新中)

    命令名 用法 安装上传下载 yum install lrzsz   rz上传文件,sz下载文件 压缩 解压文件 tar -zxvf  文件名 压缩文件 tar -zcvf 文件名 删除非空目录: rm ...

  3. JavaScript利用数组原型,添加方法实现遍历多维数组每一个元素

    原型就是提供给我们为了让我们扩展更多功能的. 今天学习了用js模拟底层代码,实现数组多维的遍历.思想是在数组原型上添加一个方法. // js中的数组forEach方法,传入回掉函数 能够帮助我们遍历数 ...

  4. 框架学习之Struts2(四)---拦截器和标签

    一.拦截器概述 1.1 在struts2框架中封装了很多功能,struts2里面封装的功能都是在拦截器里面,struts2里面又很多拦截器,但不是每次这些拦截器都执行,每次执行型默认的拦截器. 默认拦 ...

  5. ipv4与ipv6的区别

    对于计算机网络有一定了解的园园们来说,对这两个概念应该比较熟悉,我也将我知道的一点点小知识分享给大家吧 1.协议使用的广泛程度不同 目前,ipv4得到了广泛的应用,基本上所以的与上网有关的(看电影,玩 ...

  6. Beautiful Soup常见的解析器

    Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快 ...

  7. Thinkphp框架下连接两个及以上的数据库方法

    在我们的实际开发者,我们经常需要链接两个以上的数据库,方法跟简单 Thinkphp文档中也有介绍:点击查看 方法如下: 第一步:配置文件config.php <?php //默认数据库1 ret ...

  8. Linux云服务器安装Elasticsearch

    安装Elasticsearch 注:本人服务器为CentOS7.3镜像 1.下载JDK 在安装JDK之前需要检查是否已存在其他版本JDK. 采用如下命令可查看当前已存在JDK版本: java -ver ...

  9. thinkjs升级到3.0后的图片上传

    似乎当thinkjs升级到3.0后,才接手了一个项目.只是在实际运用过程中,还是发现了与2.2的些许差别——今天先分享关于图片上传的一些问题. 1.上传文件,我们选择了jQuery的插件:http:/ ...

  10. 谈谈App的混合开发

    一.概念 App混合开发,顾名思义,是一个开发模式,指的是开发一个App一部分功能用native构建一部分功能用html5构建,英文名叫:Hybrid App. 在几年前就已经出现了App混合开发模式 ...