python3内置持久化模块shelve心得

python3内置持久化模块shelve心得

来自python官方网站的解释:
https://docs.python.org/zh-cn/3.10/library/shelve.html
本文环境: Windows 10 专业版 64 位 + Thonny 3.2.6

概述

内置模块 shelve 可以将任意 Python 对象(即 https://docs.python.org/zh-cn/3.10/library/pickle.html#module-pickle 模块能够处理的任何东西。)以类似字典的对象(shelf 对象)存在磁盘上以实现数据的持久保存。模块 shelve 生成的类似字典的对象 shelf 包含键 key 和 值 value 。类字典对象 shelf 的键 key 是普通的字符串。类字典对象 shelf 的值 value 是任意 python 对象—即 pickle 模块能够处理的任何东西。
在这里插入图片描述

【个人猜想 python 使用 shelve 作为数据持久化模块名字的原因】
shelve释义 vt. 将(书等)放置在架子上。通过上述表格可以理解 python 使用 shelve (释义 vt. 将(书等)放置在架子上)作为数据持久化模块名字的原因。把 python 对象加上标签放在磁盘中。
内置持久化模块 pickle 和 shelve 的区别?
内置模块 pickle 是一条一条的存储数据的,没有给数据贴上便于索引的标签。内置模块 shelve 是 pickle 升级,底层用到了 pickle 的方法,把 python 对象贴上标签后存储在磁盘中。

语法

打开一个持久化字典shelve.open()

shelve.open(filename, flag=‘c’, protocol=None, writeback=False)
语句作用:打开一个持久化字典。
参数
filename :必填参数。filename 指定下层数据库的基准文件名。作为附带效果,会为 filename 添加一个扩展名并且可能创建更多的文件。
flag=‘c’ :可选参数。默认值 ‘c’ 读写模式。默认情况下,下层数据库会以读写模式打开。可选的 flag 形参具有与 https://docs.python.org/zh-cn/3.10/library/dbm.html#dbm.open flag 形参相同的含义。
protocol=None :可选参数。默认值 None。在默认情况下,会使用以 https://docs.python.org/zh-cn/3.10/library/pickle.html#pickle.DEFAULT_PROTOCOL 创建的 pickle 来序列化值。 pickle 协议的版本可通过 protocol 形参来指定。
writeback=False :可选参数。默认值 False。由于 Python 语义的限制,Shelf 对象无法确定一个可变的持久化字典条目在何时被修改。 默认情况下 只有 在被修改对象再赋值给 shelf 时才会写入该对象 (参见 https://docs.python.org/zh-cn/3.10/library/shelve.html#shelve-example)。 如果可选的 writeback 形参设为 True,则所有被访问的条目都将在内存中被缓存,并会在 https://docs.python.org/zh-cn/3.10/library/shelve.html#shelve.Shelf.sync 和 https://docs.python.org/zh-cn/3.10/library/shelve.html#shelve.Shelf.close 时被写入;这可以使得对持久化字典中可变条目的修改更方便,但是如果访问的条目很多,这会消耗大量内存作为缓存,并会使得关闭操作变得非常缓慢,因为所有被访问的条目都需要写回到字典(无法确定被访问的条目中哪个是可变的,也无法确定哪个被实际修改了)。

关闭一个持久化字典shelf.close()

shelf.close()

推荐使用上下文管理器with shelve.open(‘spam’) as db:

with shelve.open(‘spam’) as db:
db[‘eggs’] = ‘eggs’

解析:
with shelve.open(‘spam’) as db:
with :上下文管理器, with 会自动关闭文件。
shelve.open() : 模块 shelve 的 open 方法,使用读写模式创建名为 spam 的类字典对象 shelf ,在我的电脑上生成了3个文件: spam.bak 、 spam.dat 、spam.dir 。
在这里插入图片描述

这3个文件都用系统自带的记事本打开:
spam.bak :‘egg’, (0, 13)
spam.dat :€X eggq .
spam.dir :‘egg’, (0, 13)
在这里插入图片描述

as db :指定用 shelve.open() 打开的类字典文件对象 shelf 的别名是 db 。
db[‘eggs’] = ‘eggs’ : 向类字典对象 shelf 中添加键值对 , 键 ‘egg’ ,值字符串 ‘egg’ 。

示例

来在官网的示例:

在这里插入图片描述

解析及翻译:

import shelve

d = shelve.open(filename)  # open -- file may get suffix added by low-level library
                           # 打开 -- 文件可能从尾部加入通过低级别的库

d[key] = data              # store data at key (overwrites old data if using an existing key)
                           # 存储变量名data中的数据value到键key(如果键key已经保存有数据,原有数据会被覆盖)
data = d[key]              # retrieve a COPY of data at key (raise KeyError if no such key)
                           # 从键key中取回数据赋值给变量名data(如果没有键名 key 系统提起 KeyError 错误)
del d[key]                 # delete data stored at key (raises KeyError if no such key)
                           # 删除键 key 及数据(如果没有键名 key 系统提起 KeyError 错误)

flag = key in d            # true if the key exists
                           # 使用关键字 in 检测一个键 key 是否在类字典对象 shelf d中
klist = list(d.keys())     # a list of all existing keys (slow!)
                           # 使用函数 list() 列出类字典对象 shelf d中的全部键 key

# as d was opened WITHOUT writeback=True, beware:
# 类字典对象 shelf d 打开没用使用 writeback=True , 小心:
d['xx'] = [0, 1, 2]        # this works as expected, but...
                           # 向类字典文件对象 shelf d 写入键-值对
                           # 键 key 'xx' ,值 value 列表 [0, 1, 2]
d['xx'].append(3)          # *this doesn't!* -- d['xx'] is STILL [0, 1, 2]!
                           # 通过列表的内置方法append()试图加入元素3
                           # 由于 open() 是没有使用参数 writeback = True
                           # 导致添加元素3失败 --  d['xx'] 的值还是[0, 1, 2]!
# having opened d without writeback=True, you need to code carefully:
# 如果open()文件类字典文件对象 shelf d 是没有使用参数 writeback = True , 你编程时需要小心:
temp = d['xx']             # extracts the copy
                           # 把类字典对象 shelf d['xx']键中保存的值,赋值给temp
temp.append(5)             # mutates the copy
                           # 对变量 temp 进行列表的 append 操作
d['xx'] = temp             # stores the copy right back, to persist it
                           # 类字典对象 shelf d['xx']的键再次指向 temp
# or, d=shelve.open(filename,writeback=True) would let you just code
# d['xx'].append(5) and have it work as expected, BUT it would also
# consume more memory and make the d.close() operation slower.
# 或者,d=shelve.open(filename,writeback=True)
# d['xx'].append(5) 可以正常工作,但是 writeback=True 会导致
# 消耗更多的内存和关闭文件对象 d.close() 时变慢。
d.close()                  # close it
                           # 类字典文件对象 shelf d 关闭

包含常用操作的示例

# 模块 shelve 训练
import shelve

my_str = "abcde"
my_list = [1,2,3,4,5]
my_tuple = (100,200)
my_dict = {
    'name':'qs',
    'age':18,
    }

shelf_object = shelve.open('shelve_test') # 新建一个用模块shelve存储在硬盘上的文件shelve_test 
shelf_object['shelf_str1'] = my_str
shelf_object['shelf_list1'] = my_list
shelf_object['shelf_tuple1'] = my_tuple
shelf_object['shelf_dict1'] = my_dict
shelf_object['shelf_str2'] = 'fghijk'
shelf_object.close() # 关闭类字典 shelf 对象,以上数据存储到硬盘上3个文件,
                     # 名为shelve_test后缀名:bak、dat、dir
with shelve.open('shelve_test') as shelf_object: # 使用上下文管理器 with 打开文件 shelve_test 生成类字典对象 shelf 文件名 db
                                                 # 使用了 with python 会自动 close() 类字典文件对象 shelf db
    print(list(shelf_object.keys()))             # 列出文件 shelve_test 内存储的所有键 keys
    print(list(shelf_object.values()))           # 列出文件 shelve_test 内出存储的所有值 values
    for k,v in shelf_object.items():             # 使用 for 循环和字典的items() 方法遍历键 key 和值 value
        print("键:",k)
        print("值:",v)
        print("**********\n")
        
    flag = 'shelf_str1' in shelf_object          # 使用关键字 in 判断键 key 是否在 shelf 文件内
    print("判断键是否在文件内 key in shelf_object:",flag)

结果:

>>> %Run shelve_test.py
['my_str', 'my_list', 'shelf_str1', 'shelf_list1', 'shelf_tuple1', 'shelf_dict1', 'shelf_str2']
['abcde', ['abc', 'def'], 'abcde', [1, 2, 3, 4, 5], (100, 200), {'name': 'qs', 'age': 18}, 'fghijk']
键: my_str
值: abcde
**********

键: my_list
值: ['abc', 'def']
**********

键: shelf_str1
值: abcde
**********

键: shelf_list1
值: [1, 2, 3, 4, 5]
**********

键: shelf_tuple1
值: (100, 200)
**********

键: shelf_dict1
值: {'name': 'qs', 'age': 18}
**********

键: shelf_str2
值: fghijk
**********

判断键是否在文件内 key in shelf_object: True
>>> 

参数 writeback = True

shelve.open() 默认 writeback = False ,会导致我们修改类字典文件 shelf 的内容失败。可以使用参数 writeback = True 来解决。示例如下:

# 模块 shelve 训练
import shelve

my_dict = {
    'name':'qs',
    'age':18,
    }

with shelve.open('shelve_test') as shelf_object:
    shelf_object['key1'] = my_dict # 将字典 my_dict 存入 shelf_object

print("默认值 writeback = False ")    
with shelve.open('shelve_test') as shelf_object:    
    print(shelf_object['key1'])           # 字典 my_dict 存入 shelf_object 成功
    print("修改前shelf_object['key1']['name']的值:")
    print(shelf_object['key1']['name'])   # 读出 shelf_object['key1']['name'] 键对应的值成功
    shelf_object['key1']['name'] = 'abc'  # shelf_object['key1']['name'] 键对应的值赋值为 'abc'
    print("修改后shelf_object['key1']['name']的值:")
    print(shelf_object['key1']['name'])   # shelf_object['key1']['name'] 键对应的值赋值为 'abc' 失败

print(" writeback = True ") 
with shelve.open('shelve_test',writeback = True) as shelf_object:
    print(shelf_object['key1'])           # 字典 my_dict 存入 shelf_object 成功
    print("修改前shelf_object['key1']['name']的值:")
    print(shelf_object['key1']['name'])   # 读出 shelf_object['key1']['name'] 键对应的值成功
    shelf_object['key1']['name'] = 'abc'  # shelf_object['key1']['name'] 键对应的值赋值为 'abc'
    print("修改后shelf_object['key1']['name']的值:")
    print(shelf_object['key1']['name'])   # shelf_object['key1']['name'] 键对应的值赋值为 'abc' 成功 

结果:

>>> %Run shelve_test.py
默认值 writeback = False 
{'name': 'qs', 'age': 18}
修改前shelf_object['key1']['name']的值:
qs
修改后shelf_object['key1']['name']的值:
qs
 writeback = True 
{'name': 'qs', 'age': 18}
修改前shelf_object['key1']['name']的值:
qs
修改后shelf_object['key1']['name']的值:
abc
>>> 

如果大家想更深入了解shelve的模块,推荐大家阅读【乐铁】博主创作的文章:
铁乐学python-shelve模块详解,同时感谢【乐铁】博主创作这么好的文章。
文章链接:
https://blog.csdn.net/u012145252/article/details/80028146

1、shelve模块将内存数据以字典的类型(key,value)通过文件持久化,模拟出简单的db效果。
2、shelve模块可以持久化任何pickle可支持的python数据格式,但是它的key必需得是字符串。
3、shelve可以看作是pickle模块的一个封装,但它实现了可以多次dump(后面的dump不会覆盖前面的)和多次load。
4、shelve访问己有key时,实际上取出的是数据源给出的一份拷贝,
所以对于拷贝做出的增加和删除等操作都需要用writeback=True参数才能实现写入回源中进行修改。
5、shelve对于d[key] = data这种操作,视为存储数据,无则新增,有则覆盖,
与访问key对当中的值(条目)进行修改默认不回写并不矛盾和冲突。
6、默认安装环境下,shelve中的r只读模式在python2.7能生效,在3.5环境中则不能生效。
有很大可能是与2.7中存在anydbm模块,而3.5中只存在dbm模块而不存在anydbm有关。
————————————————

                        版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/u012145252/article/details/80028146

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/522182.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第29篇:秒表计时器

Q:本期我们采用计数器来实现秒表计时器,循环进行0~9计时。 A:在数码管HEX0上循环从0到9计数,间隔时间为1s,使用计数器实现1s时间间隔。 DE2-115开发板提供了50MHz时钟,触发器直接以50MHz信号作为同步时钟…

C++ | Leetcode C++题解之第11题盛最多水的容器

题目&#xff1a; 题解&#xff1a; class Solution { public:int maxArea(vector<int>& height) {int l 0, r height.size() - 1;int ans 0;while (l < r) {int area min(height[l], height[r]) * (r - l);ans max(ans, area);if (height[l] < height[r…

鸿蒙实现一种仿小红书首页滑动联动效果

前言&#xff1a; DevEco Studio版本&#xff1a;4.0.0.600 效果描述&#xff1a;通过手指滑动列表&#xff0c;控制位置显示效果为&#xff1a;不论列表在什么位置下滑时下图粉色位置布局显示&#xff0c;手指上滑时下图粉色位置布局隐藏。 效果&#xff1a; 原理分析&…

简单介绍css及其代码样式

css简介 css用于前端开发&#xff0c;负责对界面进行美化。让页面更美观。 他可以改变html代码的样式&#xff0c;让html代码的网页不那么死板。 css代码格式 选择器 {属性:值; 属性:值&#xff1b;} css的模版架构 css代码放到<style>标签中。 而<style>通常是…

2024/4/7周报

文章目录 摘要Abstract文献阅读题目引言创新点Decoder-Encoder模型实验过程实验结果 深度学习LSTM变体Bidirectional LSTM&#xff08;双向LSTM&#xff09;GRUGRU代码实现 总结 摘要 用于统计机器翻译的RNN编码器-解码器学习短语表示 文中提出了一种新的神经网络模型称为RNN编…

博客评论回复03

接着之前写的&#xff0c;之前返回的数据集按道理来说渲染出来还是丑丑的&#xff0c;因此这次我看着抖音的评论样子&#xff0c;自己瞎写了一通&#xff0c;不过也算是模仿出来了虽然肯定没有抖音写的好。 类似与前面几章写的表结构 首先看看抖音评论区是怎么样的&#xff1f…

消息队列之RabbitMQ的安装配置

一&#xff0c;前言 RabbitMQ是由erlang语言开发&#xff0c;基于AMQP&#xff08;Advanced Message Queue 高级消息队列协议&#xff09;协议实现的消息队列&#xff0c;它是一种应用程序之间的通信方法&#xff0c;消息队列在分布式系统开发中应用非常广泛。点击跳转RabbitM…

前端开发学习笔记 3 (Chrome浏览器调试工具、Emmet语法、CSS复合选择器、CSS元素选择模式、CSS背景)

文章目录 Chrome浏览器调试工具Emmet语法CSS复合选择器后代选择器子选择器并集选择器伪类选择器 CSS元素选择模式元素选择模式概述CSS块标签CSS行内标签CSS行内块标签CSS元素显示模式转换 CSS背景CSS背景颜色CSS背景图片CSS背景图片平铺CSS背景图片位置CSS背景图片固定CSS背景复…

HIS系统是什么?一套前后端分离云HIS系统源码 接口技术RESTful API + WebSocket + WebService

HIS系统是什么&#xff1f;一套前后端分离云HIS系统源码 接口技术RESTful API WebSocket WebService 医院管理信息系统(全称为Hospital Information System)即HIS系统。 常规模版包括门诊管理、住院管理、药房管理、药库管理、院长查询、电子处方、物资管理、媒体管理等&…

275. 传纸条(DP)

题目描述 小渊和小轩是好朋友也是同班同学&#xff0c;他们在一起总有谈不完的话题。一次素质拓展活动中&#xff0c;班上同学安排坐成一个 m 行 n 列的矩阵&#xff0c;而小渊和小轩被安排在矩阵对角线的两端&#xff0c;因此&#xff0c;他们就无法直接交谈了。幸运的是&…

CMU15/445 2023 Spring-project1 LRU-K 替换策略

在写个demo之前&#xff0c;专门学习了LRU:【LeetCode刷题】146. LRU 缓存-CSDN博客 使用哈希表 双向链表可以满足删除/增加的时间复杂度为O(1)。 在通读完15/445这块的说明之后&#xff0c;发现和LRU还是有些差别的。 官方文档中对LRU-K的解释是&#xff1a;LRU-K算法根据所…

Spring boot框架Rouyi Cloud入门之token

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 往期热门专栏回顾 专栏…

【Gluten】Spark 的向量化执行引擎框架 Gluten

Gluten 项目主要用于“粘合” Apache Spark 和作为 Backend 的 Native Vectorized Engine。Backend 的选项有很多&#xff0c;目前在 Gluten 项目中已经明确开始支持的有 Velox、Clickhouse 和 Apache Arrow。通过使用Native backend 执行计算&#xff0c;加速 Spark 执行速度&…

超市商品管理系统的设计与实现(全套资料)

一、系统架构 前端&#xff1a;vue | view-design 后端&#xff1a;springboot | mybatis-plus 环境&#xff1a;jdk17 | mysql8 | maven | nodejs | redis 二、代码及数据库 三、功能介绍 01. web端-首页 02. web端-超市概况 03. web端-超市区域 04. …

【Web】纯萌新的BUUCTF刷题日记Day1

目录 [RoarCTF 2019]Easy Java [网鼎杯 2018]Fakebook [CISCN2019 华北赛区 Day2 Web1]Hack World [BJDCTF2020]The mystery of ip [网鼎杯 2020 朱雀组]phpweb [BSidesCF 2020]Had a bad day [BJDCTF2020]ZJCTF&#xff0c;不过如此 [BUUCTF 2018]Online Tool [GXYCTF…

并发 ---- 多线程原理及底层实现

并发现象遍布日常生活&#xff0c;我们时常接触&#xff1a;我们可以边走路边说话&#xff1b;或者&#xff0c;左右手同时做出不一样的动作。在计算机应用程序中也有很好的例子&#xff1a; 浏览器 - 浏览器可以同时下载任意数量的文件和打开多个网页&#xff0c;下载时仍允许…

观测线程的工具——jconsole

joconsole的简单使用 joncole位置在jdk/bin路径中&#xff0c;在进入路径后可以查找到jconsole.exe的应用程序。如图&#xff1a; 双击创建jconsole进程&#xff0c;可以在里面选择所要观测的java文件。 以我的代码为例&#xff1a; class MyThread extends Thread {Overrid…

用户侧终端表计--预付费电表/费控/时间控制/负载控制/远程充值/远程抄表/分时计量/定量电能表/多回路预付费电表

预付费电表&#xff08;先付费后用电&#xff09;又叫做定量电能表&#xff0c;除了具有普通电能表的计量功能外&#xff0c;特别的是用户先买电&#xff0c;买电后才能用电&#xff0c;若用完电后用户不继续买电&#xff0c;则自动切断电源停止供电。 安科瑞薛瑶瑶1870170908…

Spark编程基础

一、RDD入门 1.RDD是什么&#xff1f; RDD是一个容错的、只读的、可进行并行操作的数据结构&#xff0c;是一个分布在集群各个节点中的存放元素的集合&#xff0c;即弹性分布式数据集。 2.RDD的三种创建方式 第一种是将程序中已存在的集合&#xff08;如集合、列表、数组&a…

【JavaSE零基础】00-基础语法(1-12章)

1 第一章 Java开发环境搭建 1.1 章节目标与知识框架 1.1.1 章节目标 掌握Java的开发环境搭建&#xff0c;会编写HelloWorld程序&#xff0c;并能够准确的进行编译和运行&#xff1b;理解path和classpath环境变量并可以自行配置。 1.1.2 知识框架 1.2 Java语言概述(了解) J…