Python3 shelve对象持久存储原理详解


Posted in Python onMarch 23, 2020

1.shelve对象的持久存储

不需要关系数据库时,可以用shelve模块作为持久存储Python对象的一个简单的选择。类似于字典,shelf按键访问。值将被pickled并写至由dbm创建和管理的数据库。

1.1 创建一个新shelf

使用shelve最简单的方法就是利用DbfilenameShelf类。它使用dbm存储数据。这个类可以直接使用,也可以通过调用shelve.open()来使用。

import shelve
with shelve.open('test_shelf.db') as s:
  s['key1'] = {
    'int': 10,
    'float': 9.5,
    'string': 'Sample data',
  }

再次访问这个数据,可以打开shelf,并像字典一样使用它。

import shelve
with shelve.open('test_shelf.db') as s:
  existing = s['key1']
print(existing)

运行这两个示例脚本会生成以下输出。

Python3 shelve对象持久存储原理详解

dbm模块不支持多个应用同时写同一个数据库,不过它支持并发的只读客户。如果一个客户没有修改shelf,则可以通过传入flag='r'来告诉shelve以只读方式打开数据库。

import dbm
import shelve
with shelve.open('test_shelf.db', flag='r') as s:
  print('Existing:', s['key1'])
  try:
    s['key1'] = 'new value'
  except dbm.error as err:
    print('ERROR: {}'.format(err))

如果数据库作为只读数据源打开,并且程序试图修改数据库,那么便会生成一个访问错误异常。具体的异常类型取决于创建数据库时dbm选择的数据库模块。

Python3 shelve对象持久存储原理详解

1.2 写回

默认的,shelf不会跟踪对可变对象的修改。这说明,如果存储在shelf中的一个元素的内容有变化,那么shelf必须再次存储整个元素来显式的更新。

import shelve
with shelve.open('test_shelf.db') as s:
  print(s['key1'])
  s['key1']['new_value'] = 'this was not here before'
with shelve.open('test_shelf.db', writeback=True) as s:
  print(s['key1'])

在这个例子中,没有再次存储'key1'的相应字典,所以重新打开shelf时,修改不会保留。

Python3 shelve对象持久存储原理详解

对于shelf中存储的可变对象,要想自动捕获对它们的修改,可以在打开shelf时启用写回(writeback)。writeback标志会让shelf使用内存中缓存以记住从数据库获取的所有对象。shelf关闭时每个缓存对象也被写回到数据库。

import shelve
import pprint
with shelve.open('test_shelf.db', writeback=True) as s:
  print('Initial data:')
  pprint.pprint(s['key1'])
  s['key1']['new_value'] = 'this was not here before'
  print('\nModified:')
  pprint.pprint(s['key1'])
with shelve.open('test_shelf.db', writeback=True) as s:
  print('\nPreserved:')
  pprint.pprint(s['key1'])

尽管这会减少程序员犯错的机会,并且使对象持久存储更透明,但是并非所有情况都有必要使用写回模式。打开shelf时缓存会消耗额外的内容,关闭shelf时会暂时将各个缓存对象写回到数据库,这会减慢应用的速度。所有缓存的对象都要写回数据库,因为无法区分它们是否有修改。如果应用读取的数据多于写的数据,那么写回就会影响性能而没有太大意义。

Python3 shelve对象持久存储原理详解

1.3 特定shelf类型

之前的例子都使用了默认的shelf实现。可以使用shelve.open()而不是直接使用某个shelf实现,这是一种常用的用法,特别是使用什么类型的数据库来存储数据并不重要时。不过,有些情况下数据库格式会很重要。在这些情况下,可以直接使用DbfilenameShelf或BsdDbshelf,或者甚至可以派生Shelf来得到一个定制解决方案。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python比较2个xml内容的方法
May 11 Python
python保存字符串到文件的方法
Jul 01 Python
Python简单实现子网掩码转换的方法
Apr 13 Python
使用requests库制作Python爬虫
Mar 25 Python
Python基于TCP实现会聊天的小机器人功能示例
Apr 09 Python
python 自动批量打开网页的示例
Feb 21 Python
python and or用法详解
Jun 26 Python
python 缺失值处理的方法(Imputation)
Jul 02 Python
python中count函数简单用法
Jan 05 Python
浅析matlab中imadjust函数
Feb 27 Python
Python3批量创建Crowd用户并分配组
May 20 Python
Python特殊属性property原理及使用方法解析
Oct 09 Python
python新式类和经典类的区别实例分析
Mar 23 #Python
Python count函数使用方法实例解析
Mar 23 #Python
使用python实现飞机大战游戏
Mar 23 #Python
如何在Django中使用聚合的实现示例
Mar 23 #Python
python3注册全局热键的实现
Mar 22 #Python
浅谈Python线程的同步互斥与死锁
Mar 22 #Python
Django 项目布局方法(值得推荐)
Mar 22 #Python
You might like
PHP中ini_set和ini_get函数的用法小结
2014/02/18 PHP
ThinkPHP使用PHPExcel实现Excel数据导入导出完整实例
2014/07/22 PHP
常见php数据文件缓存类汇总
2014/12/05 PHP
php array_keys 返回数组的键名
2016/10/25 PHP
Dom在ajax技术中的作用说明
2010/10/25 Javascript
js获取TreeView控件选中节点的Text和Value值的方法
2012/11/24 Javascript
jquery数据验证插件(自制,简单,练手)实例代码
2013/10/24 Javascript
JavaScript1.6数组新特性介绍以及JQuery的几个工具方法
2013/12/06 Javascript
JavaScript对象学习小结
2015/09/02 Javascript
详解javascript中的事件处理
2015/11/06 Javascript
JavaScript数组的一些奇葩行为
2016/01/25 Javascript
理解javascript定时器中的单线程
2016/02/23 Javascript
jqGrid用法汇总(全经典)
2016/06/28 Javascript
VC调用javascript的几种方法(推荐)
2016/08/09 Javascript
jQuery获取选中单选按钮radio的值
2016/12/27 Javascript
postman+json+springmvc测试批量添加实例
2018/03/31 Javascript
layui table 参数设置方法
2018/08/14 Javascript
详解vue移动端项目代码拆分记录
2019/03/15 Javascript
关于AOP在JS中的实现与应用详解
2019/05/06 Javascript
前端插件之Bootstrap Dual Listbox使用教程
2019/07/23 Javascript
Vue实现简单购物车功能
2020/12/13 Vue.js
[02:18]DOTA2英雄基础教程 育母蜘蛛
2014/01/20 DOTA
python 3.0 模拟用户登录功能并实现三次错误锁定
2017/11/01 Python
python3实现多线程聊天室
2018/12/12 Python
Python读写文件基础知识点
2019/06/10 Python
python中使用ctypes调用so传参设置遇到的问题及解决方法
2019/06/19 Python
django框架使用views.py的函数对表进行增删改查内容操作详解【models.py中表的创建、views.py中函数的使用,基于对象的跨表查询】
2019/12/12 Python
Python+redis通过限流保护高并发系统
2020/04/15 Python
Python 如何测试文件是否存在
2020/07/31 Python
python解包概念及实例
2021/02/17 Python
英国领先的办公用品供应商:Viking
2016/08/01 全球购物
俄罗斯第一家篮球店:StreetBall
2020/07/30 全球购物
广告设计应届生求职信
2014/03/01 职场文书
《美丽的丹顶鹤》教学反思
2014/04/22 职场文书
平安工地建设方案
2014/05/06 职场文书
opencv-python图像配准(匹配和叠加)的实现
2021/06/23 Python