pickle 更快的数据储存方式

存储 存储软件
很多人会选择将数据写入一个文本文档,使用时再将之读入。这固然是一种解决办法,但不够“优雅”,今天我们将会介绍一种优雅的python读写数据对象的方式:pickle模块。

在之前的python系列推文中,我们介绍了文件读写系列函数,也介绍了诸多python中的原生数据类型,这是每一个学习python语言的人都应该掌握的知识。而如果你正逐渐将自己的数据处理工作转移到python上来,就会面临一个首要的问题————如何妥善保存python中产生的数据,如一个列表,若干个字典。很多人会选择将数据写入一个文本文档,使用时再将之读入。这固然是一种解决办法,但不够“优雅”,今天我们将会介绍一种优雅的python读写数据对象的方式:pickle模块

[[233403]]

对象的序列化(serialization)与反序列化(deserialization)

我们曾经提到,python中的所有数据类型(如列表、字典)的实例化(一个列表a = [1,2,3] ,一个字典dicta = {'name':'tom'})都可看作是一个对象(object),对象通常是一种逻辑上的实体,比如一个班级名单列表,以一个list的形式给出,则它是一个对象,一个摩尔斯电码词典,以一个dict的形式给出,则它也是一个对象,当我们想将一个列表中的信息存储下来,以备下次工作时使用时,我们也许会用文件读写函数来完成,如:

  1. classlist = ['tom','karry','bob'
  2.  
  3. with open("classlist.txt","w+"as f: 
  4.      for name in classlist: 
  5.          f.write(name+'\n'

通过使用读写函数,我们将该列表的内容分行写入一个名为classlist的列表中。当下次使用时再分行读入。

但python存在着专门读写python对象的方法,那就是pickle模块,用于解决对象的序列化与反序列化。所谓序列化指的是将python的对象转化为一种专门的二进制字符串,并将其以二进制形式写入一个文件中,而反序列化则是读取该二进制文件并将其转化回对象本身。这样子做有什么好处呢?最显而易见的是它的存储与读写速度会非常的快,后面我们会给出示例说明。其次创立专门的对象数据文件,可以防止数据被不小心修改,产生问题。

pickle模块在标准库内,引入pickle模块很简便。

  1. import pickle 

pickle dump

将对象转化为二进制存储文件使用的是pickle模块的dump方法,现在我们将一个长度为100的列表序列化并保存。

  1. import random 
  2. import pickle 
  3.  
  4. a = [random.random() for x in range(100)] 
  5.  
  6. with open("alist.pkl",'wb'as f: 
  7.      pickle.dump(a,f) 

可以看到,与一般的文件读写不同的是,我们的读写方式为wb,也就是二进制方式书写,pickle.dump方法接收两个必需的参数,***个是要序列化的对象,第二个是二进制文件句柄。执行完毕后,当前工作目录会多出来一个名为alist.pkl的文件,需要说明的是,pkl只是一个形式上的后缀名,你可以写成任何其它字符,但为了显示它是一个pickle序列化的数据对象,我们使用pkl作为标记。

pickle load

有读入就会有读取,将pkl文件读取为对象使用的是pickle模块的dump方法,现在我们将刚刚存储的数据文件读取

  1. with open("alist.pkl",'rb'as f: 
  2.      abak = pickle.load(f) 

通过这个样子即可反序列化pkl文件,变成python的列表对象。

更快的速度与更小的体积

在***节中我们提到,使用pickle来读写对象,其效率更高,我们使用time模块验证一下

  1. In [27]: import time 
  2.  
  3. In [28]: a = [random.random() for x in range(100000)] 
  4.  
  5. In [29]: with open("filewrite.txt",'w'as f: 
  6.      ...:     starttime = time.time() 
  7.      ...:     for num in a: 
  8.      ...:         f.write(str(num)+'\n'
  9.      ...:     filetime = time.time() - starttime 
  10.      ...: 
  11.  
  12. In [30]: filetime 
  13. Out[30]: 0.32804441452026367 
  14.  
  15. In [31]: with open("pklwrite.pkl",'wb'as f: 
  16.      ...:     starttime = time.time() 
  17.      ...:     pickle.dump(a,f) 
  18.      ...:     pkltime = time.time() - starttime 
  19.      ...: 
  20.  
  21. In [32]: pkltime 
  22. Out[32]: 0.10946011543273926 

可以看到,对于同样读写一个长度为100000的列表对象,使用文件读写函数所花的时间是使用了pickle模块的三倍多,当文件对象越大,差距也会越大。

我们可以查看两个文件的大小,filewrite.txt 的大小为1980kb,而pklwrite.pkl仅有880kb,在分别打包为rar文件后,大小分别为863kb与780kb,这说明序列化对象同样减少了数据存储的空间,使用pickle模块存储python数据对象是既省时间又省空间的更优雅的方法。

责任编辑:武晓燕 来源: 爬虫俱乐部
相关推荐

2012-11-14 09:29:16

MySQLGoogle数据库

2021-06-28 10:27:58

MacOSApp公证AppStore

2016-10-20 15:54:08

Python数据序列化

2021-05-19 07:50:53

Node.js数据传输

2023-12-14 07:30:04

PicklePython模块

2022-08-16 16:00:05

Python

2017-11-14 09:28:05

2011-08-01 16:24:56

云计算云安全

2011-03-03 09:11:11

开源数据库MySQLMysql数据库开发

2018-03-06 09:26:27

数据身份认证区块链

2022-09-21 10:50:43

pickledillPython

2011-03-17 08:58:09

数据储存Data StoragAndroid API

2011-07-06 09:28:06

存储数据云计算

2016-11-01 06:47:56

海底电缆数据中心

2013-12-30 15:53:35

数据处理华为闪存

2019-06-14 05:26:05

IPv6网络互联网

2013-01-17 09:21:13

大数据云计算数据分析

2023-03-27 00:17:21

eBPF技术网络

2011-07-06 10:15:52

云计算服务器云存储

2012-09-06 09:36:17

谷歌NatiShalom数据处理
点赞
收藏

51CTO技术栈公众号