引用
shelve
是一种持久化的类似字典的对象。 与dbm
数据库的区别在于shelve
中的值(不是键!)实际上可以为任意Python
对象 --- 即pickle
模块能够处理的任何东西。 这包括大部分类实例、递归数据类型,以及包含大量共享子对象的对象。 键则为普通的字符串。重点:
shelve
的key
要求必须是字符串,value
则可以是任意合法的python
数据类型。更多的详情,请查看官方文档:shelve
定义
Shelve
是对象持久化保存方法,将对象保存到文件里面,缺省(即默认)的数据存储文件是二进制的。
用途
可以作为一个简单的数据存储方案。
用法
使用时,只需要使用
open
函数获取一个shelf
对象,然后对数据进行增删改查操作,在完成工作、并且将内存存储到磁盘中,最后调用close
函数变回将数据写入文件。其对象支持字典所支持的大多数方法和运算(除了拷贝、构造器以及 | 和 |= 运算符)。
方法
shelve.open(filename, flag='c', protocol=None, writeback=False)
:创建或打开一个shelve
对象。shelve
默认打开方式支持同时读写操作。filename
:是关联的文件路径flag
:可选参数,默认为c
,如果数据文件不存在,就创建,允许读写;可以是:r
: 只读;w
: 可读写;n
: 每次调用open()
都重新创建一个空的文件,可读写。writeback
:默认为False
。当设置为True
以后,shelve
对象将为所有访问过的条目保留缓存并在close()
或sync()
时将它们写回到DB
。优点:减少了出错的概率,对持久化字典中可变条目的修改更方便。
缺点:如果访问的条目很多,这会消耗大量内存作为缓存,并会使得关闭操作变得非常缓慢,因为所有被访问的条目都需要写回到字典(无法确定被访问的条目中哪个是可变的,也无法确定哪个被实际修改了)。
shelve.close()
:同步并关闭shelve对象。注意:每次使用完毕,都必须确保shelve
对象被安全关闭。同样可以使用with shelve.open()
作为上下文管理器
代码示例
# -*- coding: utf-8 -*-
import shelve
def return_msg(code=1, msg="ok", data=None):
"""
返回数据
"""
return {
"code": code,
"msg": msg,
"data": data,
}
class ShelveHelp(object):
"""
shelve简单的使用
"""
def __init__(self, filename, flag="c"):
self.filename = filename
self.flag = flag
def write(self, **kwargs):
"""
写入数据
执行代码之后会生成三个文件,分别是:{name}.bak {name}.dat {name}.dir
"""
with shelve.open(filename=self.filename, flag=self.flag) as db:
for k, v in kwargs.items():
db[k] = v
return return_msg()
def get_data_keys(self):
"""
获取数据key列表
"""
with shelve.open(filename=self.filename, flag=self.flag) as db:
keys = list(db.keys())
return return_msg(data=keys)
def read(self):
"""
读取数据
"""
with shelve.open(filename=self.filename, flag=self.flag) as db:
keys = list(db.keys())
result = {}
for k in keys:
result[k] = db[k]
return return_msg(data=result)
def trash(self, trash_key):
"""
删除指定key数据
"""
with shelve.open(filename=self.filename, flag=self.flag) as db:
keys = list(db.keys())
if trash_key not in keys:
return return_msg(-1, trash_key + ":not exist")
del db[trash_key]
return return_msg()
def update(self, clear_all=False, **kwargs):
"""
更新数据
clear_all=True, 清除前面数据再写入,False,追加数据,相同key时会进行覆盖旧数据
"""
with shelve.open(filename=self.filename, flag=self.flag) as db:
if clear_all:
keys = list(db.keys())
for k in keys:
del db[k]
if len(kwargs) > 0:
for k, v in kwargs.items():
db[k] = v
return return_msg()
def run():
cls = ShelveHelp("test", flag="c")
def simple_write():
return cls.write(**{'h': 8888888, 'name': 99999, 'list': [1, 2, 3, 4, 5]})
def simple_read():
return cls.read()
def simple_trash(key):
return cls.trash(key)
def simple_update():
d = {
"test": "test",
"trash": "trash",
"dfdfdfd": "dfdfdfd",
"list": [1, 3, 4]
}
return cls.update(False, **d)
# 写入
# res = simple_write()
# 读取
res = simple_read()
# 废弃
# res = simple_trash("name")
# 更新
# res = simple_update()
print(res)
def test_writeback():
"""
测试回写功能(writeback=True)
shelve访问己有key时,实际上取出的是数据源给出的一份拷贝,所以对于拷贝做出的增加和删除等操作都需要用writeback=True参数才能实现写入回文件中进行修改
"""
with shelve.open(filename="hello", flag="c", writeback=True) as db:
db['list'] = [1, 2, 3]
# append
# 当writeback=False, 对数据进行修改只是在内存中的修改,修改后的数据并没有被真正写入到文件中。
db['list'].append(4)
# remove
db['list'].pop(1)
print(db['list'])
if __name__ == '__main__':
run()