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,一经查实,立即删除!

相关文章

基于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); …

stable diffusion 的 GPU 不足怎么解决

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

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

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

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…

Php_Code_challenge12

题目: 答案: 解析: 字符串拼接。

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

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

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

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

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

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

基于UML的系统分析与设计

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

Php_Code_challenge16

题目: 答案: 解析: 所以科学计数法绕过即可。

macOS Sonoma 14.4 23E214 VMware系统包下载地址,简单便捷,导入即可用!

这回分享的是VMware虚拟机macOS 14.4版本的系统包,这种系统包是已经在VMware虚拟机中安装好了的macOS系统。省去了繁琐的安装步骤与稍微漫长的等待时间。此次更新的包为诗林工作室制作的最新一个VMware系统包版本。分享给那些想快速体验macOS 14版本的朋友。 使用方…

C++ AVL树(旋转)

我们之前学习了搜索二叉树,我们知道普通的搜索二叉树会有特殊情况出现使得二叉树的两枝极其不平衡形成我们通俗说的歪脖子树: 这样的树一定会使得我们的增删查的效率变低;为了避免这种极端的情况出现,在1962年有两位伟大的俄罗斯数…

EasyExcel 复杂表头的导出(动态表头和静态表头)

问题:如图,1部分的表头是动态的根据日期变化,2部分是数据库对应的字段,静态不变的; 解决方案:如果不看1的部分,2部分内容可以根据实体类注解的方式导出,那么我们是不是可以先将动态表…

Centos7 安装 Oracle19c

下载oracle预安装包 wget http://yum.oracle.com/repo/OracleLinux/OL7/latest/x86_64/getPackage/oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm 下载19c安装包 https://www.oracle.com/cn/database/technologies/oracle-database-software-downloads.html#19c 选择…

计算机网络-HTTP相关知识-HTTPS基础

HTTP与HTTPS的区别: HTTPS在TCP和HTTP网络层之间加入了SSL/TLS安全协议层。这个安全协议层可以对数据进行加密,确保数据在传输过程中的安全。HTTPS在TCP三次握手之后,还需进行SSL/TLS的握手过程。这个握手过程主要是为了在客户端和服务器之间…

超声波清洗机是干什么用的?2024年有用的超声波清洗机推荐

随着科技的不断进步,超声波清洗机已经成为了家庭和专业场所不可或缺的高效清洁工具。它利用超声波波动产生的微小气泡来清洁物品表面及细缝中的污渍,实现深层次的清洁效果。特别是对于眼镜这样的精密物品,定期进行深度清洁不仅能够确保视觉的…

【算法刷题day10】Leetcode:232.用栈实现队列、225. 用队列实现栈

文章目录 Leetcode 232.用栈实现队列解题思路代码总结 Leetcode 225. 用队列实现栈解题思路代码总结 stack、queue和deque对比 草稿图网站 java的Deque Leetcode 232.用栈实现队列 题目:232.用栈实现队列 解析:代码随想录解析 解题思路 一个栈负责进&a…

前端二维码生成工具小程序:构建营销神器的技术解析

摘要: 随着数字化营销的不断深入,二维码作为一种快速、便捷的信息传递方式,已经广泛应用于各个领域。本文旨在探讨如何通过前端技术构建一个功能丰富、操作简便的二维码生成工具小程序,为企业和个人提供高效的营销支持。 一、引言…