一、概述

前面章节我们讲述了json和pickle模块的序列化和反序列化处理,他们有一个不足是在python 3中不能多次dump和load,shelve模块则可以规避这个问题。
shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式,是pickle 更上一层的封装。

二、shelve模块的用法

Shelve模块提供了基本的存储操作,Shelve中的open函数在调用的时候返回一个shelf对象,通过该对象可以存储内容,即像操作字典一样进行存储操作。当在该对象中查找元素时,对象会根据已经存储的版本进行重新构建,当给某个键赋值的时候,元素会被存储。

  • 持久化存储
      1 import shelve
    2
    3 def member_info(name, age):
    4 print("Member info:", name, age)
    5
    6 name = ['Jack', 'Maxwell', 'Tom']
    7 info = {'name':'Maxwell', 'age':18}
    8
    9 with shelve.open('shelve_demo') as data:
    10 data['name'] = name
    11 data['info'] = info
    12 data['func'] = member_info

    代码执行后会生成三个文件:

    其中shelve_demo.bak和shelve_demo.dir文件内容相同,显示如下:

      1 'name', (0, 43)
    2 'info', (512, 45)
    3 'func', (1024, 27)

    shelve_demo.dat猜测为类数据库文件把。

  • 解析文件内容
      1 import shelve
    2
    3 def member_info(name, age):
    4 print("Member info:", name, age)
    5
    6 with shelve.open('shelve_demo') as data:
    7 print(data['name']) #这里的key与之前保存的文件内容里面的key完全对应,否则会报错
    8 print(data['info'])
    9 print(data['func']('Alex', 22))
    10
    11 #运行结果输出:
    12 ['Jack', 'Maxwell', 'Tom']
    13 {'name': 'Maxwell', 'age': 18}
    14 Member info: Alex 22
    15 None
  • value值的修改
    一般情况下,我们通过shelve来open一个对象后,只能进行一次赋值处理,赋值后不能再次更新处理。
      1 import shelve
    2
    3 def member_info(name, age):
    4 print("Member info:", name, age)
    5
    6 name = ['Jack', 'Maxwell', 'Tom']
    7 info = {'name':'Maxwell', 'age':18}
    8
    9 with shelve.open('shelve_demo') as data:
    10 data['name'] = name
    11 data['info'] = info
    12 data['name'].append('Alex')
    13 print(data['name'])
    14
    15 程序输出:
    16 ['Jack', 'Maxwell', 'Tom'] #第一次赋值后apend的元素并没有生效

    再次open打开结果也是这样:

      1 import shelve
    2
    3 def member_info(name, age):
    4 print("Member info:", name, age)
    5
    6 name = ['Jack', 'Maxwell', 'Tom']
    7 info = {'name':'Maxwell', 'age':18}
    8
    9
    10 with shelve.open('shelve_demo') as data:
    11 print(data['name'])

    造成上述情况的原因是:我们只是修改了shelve对象的副本,而它并木有被最终保存。此时我们除了下文要讲述的update方法外,还有以下两种方法:
    方法一: shelve open一个对象后,先用临时变量指向对象副本,在临时变量上修改后让对象副本再次指向临时变量,从而覆盖保存对象副本。这种方法的本质是对open后的对象重新赋新值,并非在原有基础上进行update,也就是open后的对象内存指向地址发生了变化。

      1 import shelve
    2
    3 def member_info(name, age):
    4 print("Member info:", name, age)
    5
    6 name = ['Jack', 'Maxwell', 'Tom']
    7 info = {'name':'Maxwell', 'age':18}
    8
    9 with shelve.open('shelve_demo') as data:
    10 data['name'] = name
    11 data['info'] = info
    12 temp = data['name'] #这里的关键点在于对临时变量的使用
    13 temp.append('Alex')
    14 data['name'] = temp
    15 print(data['name'])
    16
    17 程序输出:
    18 ['Jack', 'Maxwell', 'Tom', 'Alex']

    方法二:借助open的writeback=True参数来实现,默认情况下该参数的值为False。

      1 import shelve
    2
    3 def member_info(name, age):
    4 print("Member info:", name, age)
    5
    6 name = ['Jack', 'Maxwell', 'Tom']
    7 info = {'name':'Maxwell', 'age':18}
    8
    9 with shelve.open('shelve_demo', writeback=True) as data:
    10 data['name'] = name
    11 data['info'] = info
    12 data['name'].append('Alex')
    13 print(data['name'])
    14
    15 程序输出:
    16 ['Jack', 'Maxwell', 'Tom', 'Alex']
  • update方法
    value值的更新还有一个update方法,使用起来也比较方便:
      1 import shelve
    2
    3 def member_info(name, age):
    4 print("Member info:", name, age)
    5
    6 name = ['Jack', 'Maxwell', 'Tom']
    7 info = {'name':'Maxwell', 'age':18}
    8
    9 with shelve.open('shelve_demo', writeback=True) as data:
    10 data['name'] = name
    11 data['info'] = info
    12 data.update({'name':['Jack', 'Maxwell', 'Tom', 'Alex']}) #这里也是重新赋值
    13 print(data['name'])
    14
    15 程序输出:
    16 ['Jack', 'Maxwell', 'Tom', 'Alex']

    重新load一下看看结果:

      1 import shelve
    2
    3 def member_info(name, age):
    4 print("Member info:", name, age)
    5
    6 name = ['Jack', 'Maxwell', 'Tom']
    7 info = {'name':'Maxwell', 'age':18}
    8
    9
    10 with shelve.open('shelve_demo') as data:
    11 print(data['name'])
    12
    13 程序输出:
    14 ['Jack', 'Maxwell', 'Tom', 'Alex']
  • get方法
    通过shelve.open反序列化load对象到内存后,可以通过get方法来获取key对应的value:
      1 __author__ = 'Maxwell'
    2
    3 import shelve
    4
    5 def member_info(name, age):
    6 print("Member info:", name, age)
    7
    8 name = ['Jack', 'Maxwell', 'Tom']
    9 info = {'name':'Maxwell', 'age':18}
    10
    11
    12 with shelve.open('shelve_demo') as data:
    13 print(data.get('name'))
    14
    15 程序输出:
    16 ['Jack', 'Maxwell', 'Tom', 'Alex']

三、总结

shelve概念总结:

  • shelve模块可以看做是pickle模块的升级版,因为shelve使用的就是pickle的序列化协议,但是shelve比pickle提供的操作方式更加简单、方便。
  • shelve模块相对于其它两个模块在将Python数据持久化到本地磁盘时有一个很明显的优点就是,它允许我们可以像操作dict一样操作被序列化的数据,而不必一次性的保存或读取所有数据。
  • shelve模块持久化支持更多的python数据类型

使用建议:

  1. 需要与外部系统交互时用json模块;
  2. 需要将少量、简单Python数据持久化到本地磁盘文件时可以考虑用pickle模块;
  3. 需要将大量Python数据持久化到本地磁盘文件或需要一些简单的类似数据库的增删改查功能时,可以考虑用shelve模块。

以上内容摘自大神博客http://www.cnblogs.com/yyds/p/6563608.html

day5-shelve模块的更多相关文章

  1. 小白的Python之路 day5 shelve模块讲解

    shelve模块讲解 一.概述 之前我们说不管是json也好,还是pickle也好,在python3中只能dump一次和load一次,有什么方法可以向dump多少次就dump多少次,并且load不会出 ...

  2. day5模块学习--shelve模块

    shelve模块 shelve类似于一个key-value数据库,可以很方便的用来保存Python的内存对象,其内部使用pickle来序列化数据,简单来说,使用者可以将一个列表.字典.或者用户自定义的 ...

  3. Python学习-day5 常用模块

    day5主要是各种常用模块的学习 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 conf ...

  4. Python 之路 Day5 - 常用模块学习

    本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configpars ...

  5. python序列化: json & pickle & shelve 模块

    一.json & pickle & shelve 模块 json,用于字符串 和 python数据类型间进行转换pickle,用于python特有的类型 和 python的数据类型间进 ...

  6. python pickle 和 shelve模块

    pickle和shelve模块都可以把python对象存储到文件中,下面来看看它们的用法吧 1.pickle 写: 以写方式打开一个文件描述符,调用pickle.dump把对象写进去 dn = {'b ...

  7. shelve模块

    #coding:utf-8 __author__ = 'similarface' #email:similarface@outlook.com ''' shelve模块: 映射容器 存储对象,被存储的 ...

  8. python 学习day5(模块)

    一.模块介绍 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能 ...

  9. s14 第5天 时间模块 随机模块 String模块 shutil模块(文件操作) 文件压缩(zipfile和tarfile)shelve模块 XML模块 ConfigParser配置文件操作模块 hashlib散列模块 Subprocess模块(调用shell) logging模块 正则表达式模块 r字符串和转译

    时间模块 time datatime time.clock(2.7) time.process_time(3.3) 测量处理器运算时间,不包括sleep时间 time.altzone 返回与UTC时间 ...

  10. python之shelve模块详解

    一.定义 Shelve是对象持久化保存方法,将对象保存到文件里面,缺省(即默认)的数据存储文件是二进制的. 二.用途 可以作为一个简单的数据存储方案. 三.用法 使用时,只需要使用open函数获取一个 ...

随机推荐

  1. Vue(6)- Vue-router进阶、单页面应用(SPA)带来的问题

    一.Vue-router进阶 回顾学过的vue-router,并参考官方文档学习嵌套路由等路由相关知识. 二.单页面应用(SPA)带来的问题 1.虽然单页面应用有优点,但是,如果后端不做服务器渲染(h ...

  2. 安卓使用Canvas绘制工作日程表

    有一个项目要使用工作表,选择使用canvas来绘制.实现显示工作日程的选择,可点击加入和取消,效果图:http://jwzhangjie.com/workplan.gif 自己定义控件FormView ...

  3. eslasticsearch操作集锦

    索引-index:一个索引就是一个拥有几分相似特征的文档的集合.比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引.一个索引由一个名字来标识(必须全部是小写字母的),并且 ...

  4. Mysql查询结果导出为Excel的几种方法

    本文地址:http://www.cnblogs.com/qiaoyihang/p/6398673.html 具体原文找不到了,此篇是借鉴门户的一篇文章 方法一:查询语句直接输出语法格式: Exampl ...

  5. linux内核打印级别

    1.printk()是一个内核的一个记录日志的机制,经常用来记录信息或者警告.printk可以指定输出日志的优先级,在include/linux/kern_levels.h中有相应的宏定义 #defi ...

  6. 吴超老师课程--HBASE的Java_API

    public static void main(String[] args) throws IOException { String tableName="hbase_tb"; S ...

  7. jmeter 非GUI模式下测试报错An error occurred: Unknown arg:

    D:\download\性能工具\JMeter\apache-jmeter-2.11\apache-jmeter-2.11\bin>jmeter -n -t E:\性能测试\jmeter scr ...

  8. vmvare11克隆centos虚拟机

    一.现在的虚拟机软件已经很强大了,基本上能省的操作配置,都能给用户考虑到 用vmvare安装虚拟机很简单,安装完成之后,对于不了解情况的人可能会发现虚拟机无法上网(共享主机ip的方式) 为了能够上网, ...

  9. CodeForces - 987D Fair (BFS求最短路)

    题意:有N个城市,M条双向道路连接两个城市,整个图保证连通.有K种物品,但每个城市只有一种,现在它们都需要S种物品来举办展览,可以去其他城市获取该城市的物品,花费是两城市之间的最短路径长度.求每个城市 ...

  10. Unity,基于layer的碰撞配置

    可以通过给对象指定layer,实现相同.不同layer之间碰撞的自由配置,比如我们想让怪物之间不碰撞,英雄和怪物之间碰撞,我们就可以这样指定,去掉enemies之间的勾选. 打开方式-edit-> ...