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随机生成一个6位的验证码代码分享
Mar 24 Python
在Windows服务器下用Apache和mod_wsgi配置Python应用的教程
May 06 Python
Python语言描述最大连续子序列和
Dec 05 Python
python编程测试电脑开启最大线程数实例代码
Feb 09 Python
tensorflow 输出权重到csv或txt的实例
Jun 14 Python
Django框架的使用教程路由请求响应的方法
Jul 03 Python
python实现单链表中删除倒数第K个节点的方法
Sep 28 Python
解决pycharm 远程调试 上传 helpers 卡住的问题
Jun 27 Python
用python给csv里的数据排序的具体代码
Jul 17 Python
Python学习工具jupyter notebook安装及用法解析
Oct 23 Python
python 判断文件或文件夹是否存在
Mar 18 Python
PyCharm 配置SSH和SFTP连接远程服务器
May 11 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
如何在HTML 中嵌入 PHP 代码
2015/05/13 PHP
浅析php静态方法与非静态方法的用法区别
2016/05/17 PHP
利用php-cli和任务计划实现订单同步功能的方法
2017/05/03 PHP
laravel5.1框架model类查询的实现方法
2019/10/08 PHP
clipboard.js无需Flash无需依赖任何JS库实现文本复制与剪切
2015/10/10 Javascript
JavaScript中的this机制
2016/01/30 Javascript
jQuery右下角悬浮广告实例
2016/10/17 Javascript
JS基于面向对象实现的拖拽功能示例
2016/12/20 Javascript
jQuery时间验证和转换为标准格式的时间格式
2017/03/06 Javascript
js实现多行文本框统计剩余字数功能
2017/03/28 Javascript
基于JavaScript实现瀑布流效果
2017/03/29 Javascript
基于dataset的使用和图片延时加载的实现方法
2017/12/11 Javascript
vue 将页面公用的头部组件化的方法
2017/12/18 Javascript
利用vscode调试编译后的js代码详解
2018/05/14 Javascript
Bootstrap Table 双击、单击行获取该行及全表内容
2018/08/31 Javascript
微信小程序云开发之云函数详解
2019/05/16 Javascript
JS正则表达式验证端口范围(0-65535)
2020/01/06 Javascript
ant design vue嵌套表格及表格内部编辑的用法说明
2020/10/28 Javascript
JavaScript Dom实现轮播图原理和实例
2021/02/19 Javascript
python中的编码知识整理汇总
2016/01/26 Python
python实现稀疏矩阵示例代码
2017/06/09 Python
Python数据结构之哈夫曼树定义与使用方法示例
2018/04/22 Python
python实现一个简单的udp通信的示例代码
2019/02/01 Python
django多对多表的创建,级联删除及手动创建第三张表
2019/07/25 Python
pytorch 实现tensor与numpy数组转换
2019/12/27 Python
python 将dicom图片转换成jpg图片的实例
2020/01/13 Python
Python实现钉钉订阅消息功能
2020/01/14 Python
Pandas时间序列基础详解(转换,索引,切片)
2020/02/26 Python
幼儿园义卖活动方案
2014/01/17 职场文书
幼儿园门卫安全责任书
2015/05/08 职场文书
全国助残日活动总结
2015/05/11 职场文书
简历自我评价:教师师德表现自我评价
2019/04/24 职场文书
JavaScript如何利用Promise控制并发请求个数
2021/05/14 Javascript
Vue鼠标滚轮滚动切换路由效果的实现方法
2021/08/04 Vue.js
为自由献出你的心脏!「进击的巨人展 FINAL」2022年6月在台开展
2022/04/13 日漫
MySQL远程无法连接的一些常见原因总结
2022/09/23 MySQL