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通过线程实现定时器timer的方法
Mar 16 Python
Python对象转JSON字符串的方法
Apr 27 Python
Python合并字典键值并去除重复元素的实例
Dec 18 Python
tensorflow: 查看 tensor详细数值方法
Jun 13 Python
Django基础知识与基本应用入门教程
Jul 20 Python
python 从文件夹抽取图片另存的方法
Dec 04 Python
Django forms表单 select下拉框的传值实例
Jul 19 Python
Flask教程之重定向与错误处理实例分析
Aug 01 Python
详解Python Matplotlib解决绘图X轴值不按数组排序问题
Aug 05 Python
Django使用中间件解决前后端同源策略问题
Sep 02 Python
Python GUI编程学习笔记之tkinter界面布局显示详解
Mar 30 Python
python 如何获取页面所有a标签下href的值
May 06 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中的escape函数
2013/06/29 PHP
Thinkphp和Bootstrap结合打造个性的分页样式(推荐)
2016/08/01 PHP
php-app开发接口加密详解
2018/04/18 PHP
深入理解JavaScript系列(14) 作用域链介绍(Scope Chain)
2012/04/12 Javascript
Jquery中val()表单取值赋值的实例代码
2013/08/15 Javascript
查找Oracle高消耗语句的方法
2014/03/22 Javascript
超级好用的jQuery圆角插件 Corner速成
2014/08/31 Javascript
nodejs 提示‘xxx’ 不是内部或外部命令解决方法
2014/11/20 NodeJs
Node.js和MongoDB实现简单日志分析系统
2015/04/25 Javascript
详解AngularJS中的表达式使用
2015/06/16 Javascript
jquery实现简单合拢与展开网页面板的方法
2015/09/01 Javascript
js两种拼接字符串的简单方法(必看)
2016/09/02 Javascript
Nodejs下用submit提交表单提示cannot post错误的解决方法
2016/11/21 NodeJs
Node.JS中事件轮询(Event Loop)的解析
2017/02/25 Javascript
NodeJS实现图片上传代码(Express)
2017/06/30 NodeJs
JS 中LocalStorage和SessionStorage的使用
2017/08/17 Javascript
小程序scroll-view组件实现滚动的示例代码
2018/09/20 Javascript
nuxt 路由、过渡特效、中间件的实现代码
2020/11/06 Javascript
[32:17]完美世界DOTA2联赛循环赛LBZS vs Forest第二场 10月30日
2020/10/31 DOTA
分析用Python脚本关闭文件操作的机制
2015/06/28 Python
pycharm+PyQt5+python最新开发环境配置(踩坑)
2019/02/11 Python
python实现图像检索的三种(直方图/OpenCV/哈希法)
2019/08/08 Python
python中bytes和str类型的区别
2019/10/21 Python
Python 识别12306图片验证码物品的实现示例
2020/01/20 Python
Numpy中np.random.rand()和np.random.randn() 用法和区别详解
2020/10/23 Python
解决PDF 转图片时丢文字的一种可能方式
2021/03/04 Python
机修工工作职责
2014/02/21 职场文书
党员干部2014全国两会学习心得体会
2014/03/10 职场文书
政协调研汇报材料
2014/08/15 职场文书
年检委托书
2014/08/30 职场文书
护士长2015年终工作总结
2015/04/24 职场文书
捐款仪式主持词
2015/07/04 职场文书
2015年科学教研组工作总结
2015/07/22 职场文书
《学会看病》教学反思
2016/02/17 职场文书
学校运动会开幕词
2016/03/03 职场文书
Nginx本地目录映射实现代码实例
2021/03/31 Servers