Python 自带小型数据库详解

news2024/10/6 2:30:43

300?wx_fmt=png&wxfrom=19


 

DBM

DBM(DataBase Manager)是一种文件系统,专门用于键值对的存储,最初是在 Unix 平台实现,现在其它平台也可以用。对于 KV 模型,DBM 提供了一个轻量级、高效的存储解决方案。

总的来说,DBM 具有如下特点:

  • 简单快速:非常简单易用,读取和写入操作都很快,适合存储少量数据。

  • 键值对存储:数据是以键值对形式存储的,你可以像操作 Python 字典一样。

  • 文件存储:数据存在具体的文件中,可以轻松地备份和转移。

  • 不支持复杂查询:如果需要执行复杂查询或需要关系型数据库的功能,DBM 可能不是一个好选择。

而 Python 标准库提供了一个 dbm 模块,它实现了 DBM 文件系统的功能,来看一下它的用法。

import dbm

# 第一个参数是文件名
# 第二个参数是模式,有以下几种
#     r:只读,要求文件必须存在,默认就是这个模式
#     w:可读可写,要求文件必须存在
#     c:可读可写,文件不存在会创建,存在则追加
#     n:可读可写,文件不存在会创建,存在则清空
# 第三个参数是权限,用八进制数字表示,默认 0o666,即可读可写不可执行
db = dbm.open("store", "c")

# 打开文件就可以存储值了,key 和 value 必须是字符串或 bytes 对象
db["name"] = "S せんせい"
db["age"] = "18"
db[b"corporation"] = "小摩".encode("utf-8")

# 关闭文件,将内容写到磁盘上
db.close()

非常简单,就像操作字典一样,并且 key 是唯一的,如果存在则替换。执行完后,当前目录会多出一个 store.db 文件。

640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1

我们打开它,然后读取刚才写入的键值对。

import dbm

db = dbm.open("store", "c")

# 获取所有的 key,直接返回一个列表
print(db.keys())
"""
[b'corporation', b'name', b'age']
"""
# 判断一个 key 是否存在,key 可以是字符串或 bytes 对象
print("name" in db, "NAME" in db)
"""
True False
"""
# 获取一个 key 对应的 value,得到的是 bytes 对象
print(db["name"].decode("utf-8"))
print(db[b"corporation"].decode("utf-8"))
"""
S せんせい
小摩
"""
# key 如果不存在,会抛出 KeyError,我们可以使用 get 方法
print(db.get("NAME", b"unknown"))
"""
b'unknown'
"""
# 当然也可以使用 setdefault 方法,key 不存在时,自动写进去
print(db.setdefault("gender", b"female"))
"""
b'female'
"""
print(db["gender"])
"""
b'female'
"""

非常简单,当你需要存储的数据量不适合放在内存中,但又没必要引入数据库,那么不妨试试使用 dbm 模块吧。

当然啦,dbm 虽然很方便,但它只能持久化 bytes 对象,字符串也是转成 bytes 对象之后再存储的。所以除了 dbm 之外,还有一个标准库模块 shelve,它可以持久化任意对象。

Shelve

shelve 的使用方式和 dbm 几乎是一致的,区别就是 shelve 的序列化能力要更强,当然速度自然也就慢一些。

import shelve

# 第二个参数表示模式,默认是 c
# 因此文件不存在会创建,存在则追加
sh = shelve.open("shelve")

sh["name"] = ["S 老师", "高老师", "电烤🐔架"]
sh["age"] = {18}
sh["job"] = {"tutu": "大学生", "xueer": "医生"}

# 关闭文件,刷到磁盘中
sh.close()

执行完之后,本地会多出一个 shelve.db 文件,下面来读取它。

import shelve

sh = shelve.open("shelve")

print(sh["name"])
print(sh["name"][2] == "电烤🐔架")
"""
['S 老师', '高老师', '电烤🐔架']
True
"""
print(sh["age"])
"""
{18}
"""
print(sh["job"])
"""
{'tutu': '大学生', 'xueer': '医生'}
"""

sh.close()

读取出来的就是原始的对象,我们可以直接操作它。

然后自定义类的实例对象也是可以的。

import shelve

class People:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @property
    def print_info(self):
        return f"name is {self.name}, age is {self.age}"

sh = shelve.open("shelve")

p = People("群主", 58)
# 将类、和该类的实例对象存储进去
sh["People"] = People
sh["p"] = p
sh.close()

执行完之后,我们打开它。

import shelve

sh = shelve.open("shelve")

# 需要注意的是,People 是我们自己定义的类
# 如果你想要将其还原出来,那么该类必须要出现在当前的命名空间中
try:
    sh["People"]
except AttributeError as e:
    print(e)
    """
    Can't get attribute 'People' on <module ...>
    """

class People:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @property
    def print_info(self):
        return f"name is {self.name}, age is {self.age}"

print(sh["People"] is People)
"""
True
"""
print(sh["p"].print_info)
"""
name is 群主, age is 58
"""
print(sh["People"]("群主", 38).print_info)
"""
name is 群主, age is 38
"""

这就是 shelve 模块,非常强大,当然它底层也是基于 pickle 实现的。如果你不需要存储复杂的 Python 对象,只需要存储字符串的话,那么还是推荐 dbm。

然后在使用 shelve 的时候,需要注意里面的一个坑。

import shelve

# 打开文件,设置键值对
sh = shelve.open("shelve")
sh["name"] = "古明地觉"
sh["score"] = [80, 80, 80]
sh.close()

# 重新打开文件,修改键值对
sh = shelve.open("shelve")
sh["name"] = "芙兰朵露"
sh["score"].append(90)
sh.close()

# 再次重新打开文件,查看键值对
sh = shelve.open("shelve")
print(sh["name"])
print(sh["score"])
"""
芙兰朵露
[80, 80, 80]
"""
sh.close()

第一次打开文件创建两个键值对,第二次打开文件将键值对修改,第三次打开文件查看键值对。但是我们发现 sh["name"] 变了,而 sh["score"] 却没变,这是什么原因?

当我们修改 name 时,采用的是直接赋值的方式,会将原本内存里的值给替换掉。而修改 score 时,是在原有值的基础上做 append 操作,它的内存地址并没有变。

所以可变对象在本地进行修改,shelve 默认是不会记录的,除非创建新的对象,并把原有的对象给替换掉。所以 sh["score"].append(90) 之后,sh["score"] 仍是 [80, 80, 80],而不是 [80, 80, 80, 90]。

因为 shelve 没有记录对象自身的修改,如果想得到期望的结果,一种方法是把对象整体换掉。也就是让 sh["score"] = [80, 80, 80, 90],这样等于是创建了一个新的对象并重新赋值,是可行的。

或者你在打开文件的时候,多指定一个参数 writeback。

import shelve

# 打开文件,设置键值对
sh = shelve.open("shelve")
sh["name"] = "古明地觉"
sh["score"] = [80, 80, 80]
sh.close()

# 重新打开文件,修改键值对
sh = shelve.open("shelve", writeback=True)
sh["name"] = "芙兰朵露"
sh["score"].append(90)
sh.close()

# 再次重新打开文件,查看键值对
sh = shelve.open("shelve")
print(sh["name"])
print(sh["score"])
"""
芙兰朵露
[80, 80, 80, 90]
"""
sh.close()

可以看到都发生改变了,但这个参数会导致额外的内存消耗。当指定 writeback=True 的时候,shelve 会将读取的对象都放到一个内存缓存当中。比如我们操作了 20 个持久化的对象,但只修改了一个,剩余的 19 个只是查看并没有做修改,但当 sh.close() 的时候,会将这 20 个对象都写回去。

因为 shelve 不知道你会对哪个对象做修改,所以不管你是查看还是修改,都会放到缓存当中,然后再一次性都写回去。这样就会造成两点影响:

  • shelve 会把我们使用的对象放到内存的另一片空间中,等于是额外拷贝了一份。

  • 虽然操作了 N 个对象,但只修改了 1 个,而 shelve 会把 N 个对象都重新写回去,从而造成性能上的问题,导致效率降低。

因此加不加这个参数,由具体情况决定。

综上所述,Python 算是自带了小型数据库,看看能不能在合适的场景中把它用上。

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

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

相关文章

借助软文,让品牌形象深入人心

品牌形象有多重要&#xff1f;独特的品牌形象能够提升市场竞争力&#xff0c;建立消费者的品牌忠诚度&#xff0c;就像蜜雪冰城的品牌形象就是实惠好喝&#xff0c;而软文作为一种推广手段&#xff0c;就能帮助企业塑造品牌形象&#xff0c;引起读者共鸣&#xff0c;今天媒介盒…

【反射】Java反射机制 -- 常用构造器与方法

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ Java反射 Java反射1. 获取class对象的三种方式…

Linux - 进程的优先级 和 如何使用优先级调度进程

理解linux 当中如何做到 把一个PCB 放到多个 数据结构当中 在Linux 当中&#xff0c;一个进程的 PCB 不会仅仅值存在一个 数据结构当中&#xff0c;他既可以在 某一个队列当中&#xff0c;又可以在 一个 多叉树当中。 队列比如 cpu 的 运行队列&#xff0c;键盘的阻塞队列等等…

性能测试用例和测试结果

性能测试用例和测试结果 一 核心业务功能的TPS测试1.1 登录接口测试用例1.2 进入首页接口测试用例1.3 添加购物车接口测试用例1.4 结算和下订单接口测试用例1.5 系统资源使用率1.6 单接口测试中一个测试的各个成员接口要单独做性能统计 二 业务流程&#xff08;多接口组合&…

word行内插入mathtype 公式后行距变大解决办法

现象 word行内插入mathtype 公式后行距变大 解决方法 选中要进行操作的那些行&#xff0c;依次单击菜单命令“格式→段落”&#xff0c;打开“段落”对话框&#xff1b;单击“缩进和间距”选项卡&#xff0c;将间距的“段前”和“段后”都调整为“0行”&#xff1b;将“如果…

中国密码算法与NIST标准对比

1. 引言 NIST定义AES为标准的对称密钥加密算法。但NIST被指出可能在加密算法中添加NSA后门。为此&#xff0c;在中国&#xff0c;ShāngM (SM) 系列密码算法&#xff0c;作为TLS 1.3集成和无线认证的备选方案&#xff1a; SM2&#xff1a;定义了认证&#xff08;签名&#xf…

薅!语雀致歉送6个月会员;万字教程讲透AI视频生成;提示词14个黄金设计法则;吴恩达AI职业规划指南 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f525; 讯飞发布星火认知大模型 V3.0&#xff0c;并推出多款大模型产品 10月24日&#xff0c;科大讯飞正式发布「星火认知大模型V3.0」&#…

layui框架实战案例(23):select编辑回显内容及事件调用

layUI框架实战案例系列文章 layui框架实战案例(21)&#xff1a;layui上传的哪些事(layui.upload组件、 file文件域、php后台上传)layui框架实战案例(20)&#xff1a;常用条件判断和信息展示技巧(图片预览、动态表格、短信已读未读、链接分享、信息脱敏、内置框架页)layui框架实…

【经验分享】openGauss容灾集群搭建

gs_sdr命令代码解读 背景 openGauss推出了容灾架构&#xff0c;相比之前的一个集群主从架构&#xff0c;而容灾架构是两个集群间的数据同步。为了更深入了解其原理&#xff0c;本文试图通过阅读gs_sdr命令相关的代码来学习下相关的各种操作。 1.容灾搭建过程可以参考&#xf…

Ragnar-lothbrok 靶机

Ragnar-lothbrok 信息搜集 存活检测 详细扫描 后台网页扫描 网站信息搜集 secret “秘密”网页 将密文保存到 password.txt 此页面使用了 wordpress CMS 疑似用户 ragnar wpscan 也爆破出了用户 ragnar wpscan --url http://10.4.7.155/wordpress/ --enumerate u 密码获…

Node.js中的单线程服务器

为了解决多线程服务器在高并发的I/O密集型应用中的不足&#xff0c;同时避免早期简单单线程服务器的性能障碍&#xff0c;Node.js采用了基于"事件循环"的非阻塞式单线程模型&#xff0c;实现了如下两个目标&#xff1a; &#xff08;1&#xff09;保证每个请求都可以…

外汇天眼:获利数倍、财务自由不是梦? 小心网络投资诈骗4阶段!

近年来网络投资愈来愈热络&#xff0c;我们经常看到有人因做加密货币、外汇交易而致富的报道&#xff0c;并开始寻找可以获利的投资机会与渠道。 然而&#xff0c;诈骗集团也注意到这个趋势&#xff0c;因此透过假冒经纪商或开设黑平台等方式&#xff0c;伺机获取不法所得。 有…

Github.io个人主页模板(进阶版)

网上很多博客感觉是有点Outdate了&#xff0c;而且通用性不强&#xff0c;希望这篇博客能给你帮助。 【保姆级教程】手把手教你用github制作学术个人主页&#xff08;学者必备&#xff09;_github个人主页模板-CSDN博客 【GitHub】用Jekyll模板快速制作github.io学术主页 - 知…

JVS低代码表单引擎之文本框的强大作用,建议收藏!

表单是低代码最基础的数据输入的方式&#xff0c;其中文本框是配置话表单的最基础的业务能力组件之一&#xff0c;主要用于收集和展示用户录入的文本类的信息&#xff0c;例如名称、地址、描述说明等等。 那么我们接下来分几个方面分别对文本框的使用进行讲解。 基础功能 拥有…

初识Java 16-1 字符串

目录 字符串的常量和变量 不变的String常量 String变量 重载的和更快的StringBuilder 容易忽略的递归现象 对字符串的操作 格式化输出 System.out.format() Formatter类 格式说明符 Formatter转换 String.format() 新特性&#xff1a;文本块 本笔记参考自&#xff…

Creaform形创HandySCAN MAX l Elite三维扫描仪便携式3D测量解决方案

CASAIM中科院广州电子智能制造事业部连续多年荣获形创Creaform战略级代理商证书。战略级代理商是形创Creaform最高级别的合作伙伴。 2023年CASAIM中科院广州电子智能制造事业部的形创Creaform战略级代理商证书&#xff1a; Creaform 形创是便携式三维测量解决方案和工程服务领…

使用mac自带VNC公网远程控制macOS

公网远程控制macOS【使用mac自带VNC】 文章目录 公网远程控制macOS【使用mac自带VNC】前言1. 测试局域网内远程控制1.1 macOS打开屏幕共享1.2 测试局域网内VNC远程控制 2. 测试公网远程控制2.1 macOS安装配置cpolar内网穿透2.2 创建tcp隧道&#xff0c;指向5900端口 3. 测试公网…

人工智能的发展方向:探索智能未来的无限可能

原创 | 文 BFT机器人 人工智能&#xff0c;简称AI&#xff0c;是一门专注于研究计算机如何能像人类一样思考、学习和解决问题的科学。它的创造初衷是构建一个智能系统&#xff0c;能模仿、模拟甚至实现人工智能的各种功能和行为&#xff0c;随着科技的持续进步&#xff0c;人工…

TSINGSEE青犀智能分析网关裸土覆盖算法如何做到防范山体滑坡?

在雨水季节&#xff0c;特别是山区&#xff0c;十分容易发生山体滑坡现象&#xff0c;会导致山村、铁路、公路、房屋、甚至城镇被冲毁&#xff0c;造成严重的人员伤亡和财产损失。而TSINGSEE青犀智能分析网关裸土覆盖算法是一种利用图像处理技术来评估裸露土壤面积和裸露程度的…

VMware打开共享虚拟机后找不到/mnt/hgfs/文件夹,以及不能拖拽/复制粘贴等操作,ubuntu不能安装VMware tools

问题原因 我的问题出现原因是&#xff0c;安装ubuntn虚拟机的时候VMware tools没有安装好&#xff0c;需要重新安装&#xff0c;但安装选项是暗的&#xff0c;不能操作。 类似这种情况&#xff0c;虚拟机开启时也是&#xff0c;因为我虚拟机已经装好了&#xff0c;开启时是亮…