python中与数据持久化有关的模块有很多,像pickle、json之类的就不介绍了,这里介绍两个其他的模块:dbm和shelve

1.dbm

'''
在一些小型程序中,不需要关系型数据库时,可以方便的用持久字典来存储键值对,和python中的字典非常类似。而且dbm的键和值都必须是str或者bytes类型
'''
import dbm

'''
这里第一个参数直接传入文件名,第二个参数表示模式
常见的模式:
r:可读,默认就是这个模式
w:可读可写
但是r、w,都必须确保文件已经存在,否则报错。

c:可读可写,文件不存在时会创建
n:可读可写,但总是会创建一个新的文件,也就是说如果创建同名文件,那么之前的内容都会被清空,也就是起不到追加的效果。

因此我们平常的模式一般都会选择c

第三个参数是权限,这个在windows下基本不用,是一组用八进制表示的数字,默认是0o666,都是可读可写不可执行
'''
db = dbm.open("store", "c")

# 打开文件之后,就可以存储值了
# 注意key和value都必须是str或者bytes类型
db["name"] = "satori"
db["age"] = "16"
db["gender"] = "f"
db["anime"] = "东方地灵殿"

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

################################################################
# 打开文件
db = dbm.open("store", "c")
print(db.keys())  # [b'name', b'age', b'gender', b'anime']
for key in db.keys():
    print(f"key={key}, value={db[key]}")
    '''
    key=b'name', value=b'satori'
    key=b'age', value=b'16'
    key=b'gender', value=b'f'
    key=b'anime', value=b'\xe4\xb8\x9c\xe6\x96\xb9\xe5\x9c\xb0\xe7\x81\xb5\xe6\xae\xbf'
    '''

  会多出这么三个文件

2.shelve

'''

shelve和dbm比较类似,但是功能远比dbm强大,因为它可以持久化任意对象
'''
import shelve

# 参数flag默认是c,因此我们只需要传入文件名就可以了,这个是自动追加在后面的
# 也就是说我写完之后,再次打开继续写的话,只会追加不会清空
sh = shelve.open("shelve")

sh["dict"] = {"name": "satori", "age": 16}
sh["list"] = [1, 2, 3, 4]
sh["set"] = {1, 2, 3, 2}

# 写完之后关闭文件,刷到内存里面
# 关闭之后就无法操作了
sh.close()

# 下面我们就可以操作数据了,下面的代码即便写在另一个py文件里面也是可以的
sh2 = shelve.open("shelve")
print(sh2["dict"], sh2["dict"].keys())  # {'name': 'satori', 'age': 16} dict_keys(['name', 'age'])
print(sh2["list"], sum(sh2["list"]))  # [1, 2, 3, 4] 10
print(sh2["set"])  # {1, 2, 3}
sh2.close()

# 可以看到,拿出来的就是原生的对象,可以直接用来进行操作的。那我们看看自己定义的类可不可以呢?
sh3 = shelve.open("shelve")

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

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

a = A("satori", 16)
# 将这个类和类的一个实例对象存储进去
sh3["A"] = A
sh3["a"] = a
sh3.close()

######################################
sh4 = shelve.open("shelve")

# sh4["A"]拿到A这个类,传入参数,调用方法
print(sh4["A"]("mashiro", "17").print_info)  # my name is mashiro, age is 17

# sh4["a"]拿到a这个实例对象,直接调用方法
print(sh4["a"].print_info)  # my name is satori, age is 16

# 我们发现依旧是可以的,说明了shelve这个模块真的很强大

  

# 我们再来看一个例子
import shelve

sh = shelve.open("shelve")
sh["list"] = [1, 2, 3]
sh["str"] = "mashiro"
sh.close()

##############################
sh = shelve.open("shelve")
sh["list"].append("xxxx")
sh["str"] = "satori"
sh.close()

#######################
sh = shelve.open("shelve")
print(sh["list"])  # [1, 2, 3]
print(sh["str"])  # satori
'''
分析结果,第一次打开文件我们创建两个键值对
sh["list"] = [1, 2, 3]
sh["str"] = "mashiro"

第二次打开文件,修改了两个键的值
第三次打开文件,打印。但是我们发现sh["str"]改变了,但是sh["list"]没有改变,这是为什么?
首先sh["str"] = "satori"很好理解,但是为什么sh["list"]没有变?
因为=,我们是直接赋值,将这一块内存里面的值给换掉,而sh["list"]我们是做append操作,这只是在原来的基础上进行修改
shelve默认情况下是不会记录,持久化对象的修改的,除非你是创建新的对象,或者是把原来的对象给换掉
如果是在原来的基础上(可变类型),比如列表、字典,进行添加或者删除操作,这些是不会被记录的
所以:sh["list"]=[1, 2, 3]  sh["list"].append("xxxx")  --->sh["list"]仍是[1, 2, 3]不会是[1, 2, 3, "xxx"]
因为shelve没有记录对象自身的修改,如果我想得到期望的结果,一种方法是把对象整体换掉
sh["list"] = [1, 2, 3, "xxxx"],这样等于是重新赋值,是可行的。但是有时候我们不知道列表里面内容,或者列表里面的内容是一些函数、类什么的、不好写的话,该咋办呢?
其实我们在打开文件的时候,还可以加上一个参数,叫做writeback
'''

  

import shelve

sh = shelve.open("shelve")
sh["list"] = [1, 2, 3]
sh["str"] = "mashiro"
sh.close()

##############################
# 如果我们需要进行修改,那么加上一个writeback=True就可以了,从名字也能看出来
# 这是会将修改的内容从新写回去
sh = shelve.open("shelve", writeback=True)
sh["list"].append("xxxx")
sh["str"] = "satori"
sh.close()

#######################
sh = shelve.open("shelve")
print(sh["list"])  # [1, 2, 3, 'xxxx']
print(sh["str"])  # satori
'''
可以看到都发生改变了,但是这个参数有缺陷,就是会有额外的内存消耗。当我们加上writeback=True的时候shelve会将我们读取的对象都放到一个内存缓存当中。
比如说我们获取了20持久化的对象,但是我们只修改了一个,剩余的19个只是查看并没有做修改,但当我们sh.close()的时候,会将这20个对象都写回去
因为shelve不知道你会对哪个对象进行修改,于是不管你是查看还是修改,都会放到缓存当中,然后再一次性都写回去。
这样会造成两点:
1.对象放到内存缓存当中,等于是重新拷贝了一份,因为我们读取文件已经到内存当中了,而shelve又把我们使用的对象放当内存的另一片空间中
2.写入数据,我们明明只修改了一份数据,但是它把20份都重新写回去了,这样会造成性能上的问题,导致效率会降低。
因此加不加这个参数,由具体情况决定
'''

  

python--数据持久化的更多相关文章

  1. python 数据序列化(json、pickle、shelve)

    本来要查一下json系列化自定义对象的一个问题,然后发现这篇博客(https://www.cnblogs.com/yyds/p/6563608.html)很全面,感谢作者,关于python序列化的知识 ...

  2. python数据的存储和持久化操作

    Python的数据持久化操作主要是六类:普通文件.DBM文件.Pickled对象存储.shelve对象存储.对象数据库存储.关系数据库存储. 普通文件不解释了,DBM就是把字符串的键值对存储在文件里: ...

  3. python:序列化与数据持久化

    数据持久化的方式有: 1.普通文件无格式写入:将数据直接写入到文件中 2.普通序列化写入:json,pickle 3.DBM方式:shelve,dbm 相关内容: json pickle shelve ...

  4. python学习总结----内置函数及数据持久化

    抽象基类(了解) - 说明: - 抽象基类就是为了统一接口而存在的 - 它不能进行实例化 - 继承自抽象类的子类必须实现抽象基类的抽象方法 - 示例: from abc import ABC, abs ...

  5. 关于python数据序列化的那些坑

    -----世界上本来没那么多坑,python更新到3以后坑就多了 无论哪一门语言开发,都离不了数据储存与解析,除了跨平台性极好的xml和json之外,python要提到的还有自身最常用pickle模块 ...

  6. Redis学习总结(1)——数据持久化

    以前研究Redis的时候,很多东西都不太明白,理解得也不太深,现在有时间重新拾起来看看,将一些心得记录下来,希望和大家一起探讨. 一.简介 Redis是一个单线程高可用的Key-Value存储系统,和 ...

  7. iOS之数据持久化方案

    概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) ...

  8. Docker数据持久化与容器迁移

    上节讲到当容器运行期间产生的数据是不会在写镜像里面的,重新用此镜像启动新的容器就会初始化镜像,会加一个全新的读写入层来保存数据.如果想做到数据持久化,Docker提供数据卷(Data volume)或 ...

  9. iOS 两行代码解决数据持久化

    在实际的iOS开发中,有些时候涉及到将程序的状态保存下来,以便下一次恢复,或者是记录用户的一些喜好和用户的登录信息等等. 这就需要涉及到数据的持久化了,所谓数据持久化就是数据的本地保存,将数据从内存中 ...

  10. iOS的数据持久化

    所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) pr ...

随机推荐

  1. 用css制作空心箭头(上下左右各个方向均有)

    平常在网页中,经常会有空心箭头,除了用图片外,可以用css来实现.基本思路是,用css绘制两个三角形,通过绝对定位让两三角形不完全重叠,例如制作向右的空心箭头,位于前面的三角形border颜色是需要的 ...

  2. [清华集训2017]无限之环(infinityloop)

    description 题面 solution 一开始的思路是插头\(DP\),然而复杂度太高 考虑将网格图黑白染色后跑费用流 流量为接口数,费用为操作次数 把一个方格拆成五个点,如何连边请自行脑补 ...

  3. BZOJ1596 [Usaco2008 Jan]电话网络 【树形dp】

    题目链接 BZOJ1596 题解 先抽成有根树 设\(f[i][0|1][0|1]\)表示以\(i\)为根,儿子都覆盖了,父亲是否覆盖,父亲是否建塔的最少建塔数 转移一下即可 #include< ...

  4. 专题训练之AC自动机

    推荐博客:http://www.cnblogs.com/kuangbin/p/3164106.html AC自动机小结 https://blog.csdn.net/creatorx/article/d ...

  5. some interesting words

    No one gets rich betting against the market. Never bet against the Fed. Bulls make money, bears make ...

  6. Ubuntu 16.04安装NVIDIA驱动后循环登录问题

    问题描述 最近买了两块NVIDIA Titan X Pascal显卡装到了服务器(运行Ubuntu 16.04)上.为了使用这两块GPU显卡,首先需要安装显卡驱动,安装方式为 #安装一个依赖文件,并更 ...

  7. [python]字符串的ljust方法

    ljust用法: string.ljust(number,'x') 格式化输出字符串,按照number数量调整字符串的总长度,ljust是左对齐,‘x’是填充字符,默认是空格 类似的还有rjust,c ...

  8. process monitor教程汇总

          这是只一个简单的例子,当然还有更复杂的规则说明,可以参考一下列表里的规则. 最后说下 process monitor 到底有什么用? 除了那些电脑高手喜欢分析程序运行情况外, 还有那些编程 ...

  9. 前端PHP入门-001-为什么学习PHP?

    写在前面的话 可能不知道能坚持多久,现在的我喜欢纯文字的描述! 希望能坚持写完,也是对自己的一个鞭策! 总顾及别人,那谁来顾及你! 为什么学习PHP? PHP入门简单,学习入门易入手[呵呵,都这么说, ...

  10. 2015/8/9 到家了,学完了CodeCademy的Python

    昨天坐了20多个小时的硬座回家.发现在网络信号差的火车上也是学习的好地方.如果你的手机电量不足的话,带上两本书简直是绝配.我在火车上阅读了两百多页的内容,并没有多大的疲累,那样无聊的环境里面能看书学习 ...