龙空技术网

Python对象持久化(序列化)——cpickle、json、shelve模块介绍

软件测试开发技术栈 460

前言:

此刻各位老铁们对“python 序列化”大概比较关怀,姐妹们都需要剖析一些“python 序列化”的相关文章。那么小编也在网摘上网罗了一些有关“python 序列化””的相关资讯,希望我们能喜欢,我们快快来学习一下吧!

在之前利用python开展数据质量分析的过程中,经常会遇到需要基于同一份中间结果分别做不同维度的分析统计,开始我们做的思路是每次都从头开始计算,后来发现在TB级别的数据背景下这种操作是非常浪费算力的,考虑到需要做数据序列化、持久化。

在实际应用中也分别使用过pickle、json、shelve来实现数据序列化。接下来与大家分享这三者的具体应用与异同。

简单讲,这三者都可以实现Python大多数对象的序列化(持久化),只是实现和应用的背景有所不同。序列化的好处是把计算处理得到的数据持久化的保存下来,当重复使用时直接通过load把数据加载到内存就可以了,避免了中间结果的重复计算,或者数据格式的重复转换。

cpickle

在python中,一般使用pickle类来进行python对象的序列化,同时cPickle(C语言编译版本)提供了一个更快速简单的实现,如官方文档所说的:"cPickle – A faster pickle",其速度大概是pickle的1000倍,因此在大多数应用程序中通常优先使用cPickle (cPickle 除了不能被继承之外,它与pickle使用基本上区别不大)。

cPickle可以对任意一种类型的python对象进行序列化操作,比如list,dict,甚至是一个类的对象等。

在cPickle中,我们使用下面方式把数据持久化至文件中:

dump函数——序列化

需要指定两个参数,第一个是需要序列化的python对象名称,第二个是本地的文件,需要使用open函数以"写"模式打开文件。

import cPickleseasons = ['Spring', 'Summer', 'Fall', 'Winter']seasons_dict = dict([(index,season) for index,season in enumerate(seasons)])cPickle.dump(seasons_dict, open("data.pickle", "wb"))

二进制格式的data.pickle文件

load函数——反序列化

载入本地文件,加载为python对象,加载出来的对象无须进行格式转换。如果通过一般写入的方式实现数据的持久化,那么在读出数据时,需要额外进行数据类型的转换。

data = cPickle.load(open("data.pickle","rb"))print data ,isinstance(data,dict)

输出

请注意,cPickle是python2 的库,在python3.x版本,改名为pickle。

缺点

pickle模块使用的数据格式是python专用的,并且不同版本不向后兼容,同时也不能被其他语言说识别。使用pickle存在安全风险,切勿反序列化不受信任或未经身份验证的pickle字节串,比如通过代码获得文件列表,进一步也可以获取文件操作等权限:

import osimport cPickleclass Exploit(object): def __reduce__(self): return (os.system, ('dir',))shellcode = cPickle.dumps(Exploit())print cPickle.loads(shellcode)

输出

获取了当前目录的文件列表

因此 pickle 方案不适合用于网络通信,可以改用另一种序列化方式,如JSON。json

json模块我们使用将数据保存到文件中,以及直接读取文件中的数据进行反序列化操作。

dump函数——序列化

将Python对象转换成json字符串并存储到文件中

import jsonseasons = ['Spring', 'Summer', 'Fall', 'Winter']seasons_dict = dict([(index,season) for index,season in enumerate(seasons)])with open('dump.json', 'w') as json_dump: json.dump(seasons_dict, json_dump, indent=4)

dump.json

load函数——反序列化

读取指定文件中的json字符串并转换成Python对象

with open('dump.json', 'r') as json_load: content = json.load(json_load)print content ,isinstance(data,dict)

输出

pickle与json区别json是一种文本序列化格式,能够读懂,而pickle是一个二进制序列化格式,无法读懂;json是与特定的编程语言或系统无关的,且它在Python生态系统之外被广泛使用,而pickle使用的数据格式是特定于Python的pickle可以直接操作大量的Python数据类型,json只能表示Python内建数据类型。shelve模块

shelve模块其内部是通过pickle协议来实现数据序列化,是一个简单的数据存储方案,类似字典的key-value数据库(key必须是字符串,value可以是任意数据类型),可以很方便的保存python字典对象,这个函数接收一个参数就是文件名。我们可以把shelf对象当dict来使用--存储、更改、查询某个key对应的数据,当操作完成之后,调用shelf对象的close()函数即可。

数据持久化至文件

import shelveseasons = ['Spring', 'Summer', 'Fall', 'Winter']seasons_dict = dict([(str(index),season) for index,season in enumerate(seasons)])shelve_dump = shelve.open('dump.shelve')#默认读写模式打开shelve_dump.update(seasons_dict)shelve_dump.close()

数据加载至内存

shelve_dump = shelve.open('dump.shelve')#默认读写模式打开print shelve_dump

输出

dump.shelve

数据修改或更新

shelve_dump = shelve.open('dump.shelve',writeback=True)shelve_dump["1"]= 'Winter'shelve_dump.update({'4':'Spring'})print shelve_dump

输出

pickle、json、shelve应用场景

1.需要与外部程序其他语言或不同版本的python程序交互时,可以考虑用json模块

2.需要将少量Python数据持久化到文件时,可以考虑用pickle模块;

3.需要将大量Python数据持久化到文件或需要对持久化对象进行增删改等操作时,可以考虑用shelve模块。

转载请说明,若对你有帮助,点赞支持哦。

标签: #python 序列化