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 shelved = 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 shelvemy_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 dbprint(list(shelf_object.keys()))             # 列出文件 shelve_test 内存储的所有键 keysprint(list(shelf_object.values()))           # 列出文件 shelve_test 内出存储的所有值 valuesfor k,v in shelf_object.items():             # 使用 for 循环和字典的items() 方法遍历键 key 和值 valueprint("键:",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 shelvemy_dict = {'name':'qs','age':18,}with shelve.open('shelve_test') as shelf_object:shelf_object['key1'] = my_dict # 将字典 my_dict 存入 shelf_objectprint("默认值 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']的值:
qswriteback = 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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

07. 【Android教程】Android 线性布局 LinearLayout

在上一节中,我们讲到了所有的 Layout 都是从 ViewGroup 继承而来,它可以包含若干 View 并按照指定的规则将这个 View 摆放到屏幕上。那么接下来的章节我们就来学习一下 Android 的 UI 布局,Android 原生有六大布局,分别是: Linear…

基于FPGA的HDMI视频接口设计

HDMI介绍 HDMI(High-DefinitionMultimedia Interface)又被称为高清晰度多媒体接口,是首个支持在单线缆上传输,不经过压缩的全数字高清晰度、多声道音频和智能格式与控制命令数据的数字接口。HDMI接口由Silicon Image美国晶像公司倡导,联合索尼、日立、松下、飞利浦、汤姆逊、东…

LLM面面观之MoE

1. 背景 根据本qiang~最新的趋势观察,基于MoE架构的开源大模型越来越多,比如马斯克的Grok-1(314B), Qwen1.5-MoE-A2.7B等,因此想探究一下MoE里面的部分细节。 此文是本qiang~针对大语言模型的MoE的整理,包括原理、流程及部分源码…

Mybatis——查询数据

查询操作 根据用户id查询单条记录,在映射器接口(UserMapper)中定义如下方法: package org.example.mapper;import org.example.demo.User;import java.util.List;public interface UserMapper {//根据id查询UserUser selectUserById(Integer userId); …

对称二叉树_递归_java

对称二叉树 leetcode链接 问题描述 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 提示&#xff1a; 树中节点数目在范围 [1, 1000] 内 -100 < Node.val < 100 示例 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;…

stable diffusion 的 GPU 不足怎么解决

稳定扩散&#xff08;stable diffusion&#xff09;是一种用于图像处理和计算机视觉任务的图像滤波算法。 当使用Stable Diffusion过程中遇到GPU显示内存不足的问题时。解决这个问题的方法有以下几种&#xff1a; 目前&#xff0c;对我来说&#xff0c;就最后一点能够暂时解决当…

GaussDB云数据库极简版安装与使用-新手指南

一、前言 作为一款领先的企业级数据库管理系统&#xff0c;GaussDB 提供了强大的性能、高度可靠性和丰富的功能&#xff0c;是企业构建可靠、高性能的数据库解决方案的理想选择。 本文主要针对高校和个人测试环境&#xff0c;介绍极简版安装和使用过程&#xff0c;更加适合高…

python多线程简单示例

Python的多线程可以帮助你在同一个进程中运行多个线程&#xff08;即任务&#xff09;&#xff0c;这样可以在执行IO密集型或高延迟的操作时提高程序的效率。下面是一个简单的Python多线程教程。 1. 引入threading模块 Python的threading模块提供了一个简单的方式来创建和管理…

如何在VSCode中高效使用Git:完全指南

引言 在软件开发领域&#xff0c;版本控制是一个至关重要的概念。它不仅仅是一个程序员的工具&#xff0c;更是团队协作、项目管理和代码质量保证的关键。随着软件开发项目的复杂性不断增加&#xff0c;版本控制系统的作用变得愈发显著。 Git作为目前最流行的分布式版本控制系…

SwiftUI Swift 选择图片 添加图片

1. 添加记帐时添加图片功能 2. Show me the code // // TestPhotoPicker.swift // pandabill // // Created by 朱洪苇 on 2024/3/30. //import SwiftUI import PhotosUI import Foundationstruct TestPhotoPicker: View {State private var selectedItem: PhotosPickerIt…

golang语言系列:SOLID、YAGNI、KISS等设计原则

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 golang语言系列 文章&#xff0c;主要对编程通用技能 SOLID、YAGNI、KISS等设计原则 进行学习 1.SOLID设计原则 S&#xff1a;SRP&#xff0c;单一职责原则O&#xff1a;OCP&#xff0c;开闭原则L&#xff1a;…

PCL拟合并绘制平面和柱面(三)

PCL绘制自定义图形 在使用PCL拟合平面和柱面后&#xff0c;需要绘制自定义大小和位置的平面和柱面以便于可视化。 //拟合类型 enum FitType {FitPlane 1, //平面FitCylinder 2 //圆柱 };主要函数&#xff1a; void PointCloudViewer(PointCloudT::Ptr cloudseg, PointC…

Php_Code_challenge12

题目&#xff1a; 答案&#xff1a; 解析&#xff1a; 字符串拼接。

文献阅读:通过 NeuronChat 从单细胞转录组推断神经元-神经元通信

文献介绍 「文献题目」 Inferring neuron-neuron communications from single-cell transcriptomics through NeuronChat 「研究团队」 聂青&#xff08;加利福尼亚大学欧文分校&#xff09; 「发表时间」 2023-02-28 「发表期刊」 Nature Communications 「影响因子」 16.6…

15 - grace序列处理 - 十三点滑动平均法

grace序列处理 -十三点滑动平均法 滑动平均是一种常用的平滑数据的方法,可以用于去除噪声或者提取趋势。十三点滑动平均是指使用窗口大小为13的滑动平均,应用于GRACE序列处理中可以去除周年项的影响。 十三点滑动平均的计算公式为: y [ n ] = ( x [ n − 6 ]

互联网轻量级框架整合之JavaEE基础I

不得不解释得几个概念 JavaEE SUN公司提出来的企业版Java开发中间件&#xff0c;主要用于企业级互联网系统的框架搭建&#xff0c;同时因为Java语言优质的平台无关性、可移植性、健壮性、支持多线程和安全性等优势&#xff0c;其迅速成为构建企业互联网平台的主流技术&#x…

关于Linux系统中Python核心包的重要性和恢复误卸载软件的方法

&#xff08;首发地址&#xff1a;学习日记 https://www.learndiary.com/2024/04/dont-remove-system-python/&#xff09; 大家好&#xff0c;我是来自淘宝网“学习日记小店”的 learndiary&#xff0c;专注于提供 Linux 相关的技术服务。昨日&#xff0c;一位使用 Ubuntu 20…

基于UML的系统分析与设计

统一建模语言(Unified Modeling Language&#xff0c;UML)是一种为面向对象系统的产品进行说明、可视化和编制文档的一种标准语言&#xff0c;是非专利的第三代建模和规约语言。UML是面向对象设计的建模工具&#xff0c;独立于任何具体程序设计语言。 毕业设计是实现本科教学培…

Php_Code_challenge16

题目&#xff1a; 答案&#xff1a; 解析&#xff1a; 所以科学计数法绕过即可。

爬虫 知识点2

article_url url_tag[href]article_response requests.get(article_url, headersheaders)article_soup BeautifulSoup(article_response.content, "html.parser")print(index)&#xff08;1&#xff09;article_url url_tag[‘href’] 这行代码从一个名为url_tag…