首页 文章资讯内容详情

python之shelve模块详解

2026-06-01 3 花语

本文内容纲要:

-一、定义 -二、用途 -三、用法 -四、关联模块Anydbm -五、方法 -六、writeback参数

一、定义

Shelve是对象持久化保存方法,将对象保存到文件里面,缺省(即默认)的数据存储文件是二进制的。

二、用途

可以作为一个简单的数据存储方案。

三、用法

使用时,只需要使用open函数获取一个shelf对象,然后对数据进行增删改查操作,在完成工作、并且将内存存储到磁盘中,最后调用close函数变回将数据写入文件。

四、关联模块Anydbm

相同点: 1.anydbm,shelve都是对象持久化保存方法,将对象保存到文件里面,缺省的数据存储文件是二进制的。这两个模块允许我们将一个磁盘上的文件与一个”dict-like”对象(类字典对象)关联起来,操作这个“dict-like”对象,就像操作dict对象一项,最后可以将“dict-like”的数据持久化到文件。 2.都可以使用open函数。 区别: anydbm的key和value的类型必须都是字符串,而shelve的key要求必须是字符串,value则可以是任意合法的python数据类型。

五、方法

1.shelve.open(filename,flag=’c’,protocol=None,writeback=False):创建或打开一个shelve对象。shelve默认打开方式支持同时读写操作。 filename是关联的文件路径。 可选参数flag,默认为‘c’,如果数据文件不存在,就创建,允许读写;可以是:‘r’:只读;’w’:可读写;‘n’:每次调用open()都重新创建一个空的文件,可读写。 protocol:是序列化模式,默认值为None。具体还没有尝试过,从pickle的资料中查到以下信息【protocol的值可以是1或2,表示以二进制的形式序列化】 2.shelve.close() 同步并关闭shelve对象。 注意:每次使用完毕,都必须确保shelve对象被安全关闭。同样可以使用with语句 withshelve.open(spam)asdb: db[eggs]=eggs

六、writeback参数

writeback:默认为False。当设置为True以后,shelf将会将所有从DB中读取的对象存放到一个内存缓存。当我们close()打开的shelf的时候,缓存中所有的对象会被重新写入DB。 writeback方式有优点也有缺点。 优点是减少了我们出错的概率,并且让对象的持久化对用户更加的透明了;但这种方式并不是所有的情况下都需要,首先,使用writeback以后,shelf在open()的时候会增加额外的内存消耗,并且当DB在close()的时候会将缓存中的每一个对象都写入到DB,这也会带来额外的等待时间。因为shelve没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入。 注意:为了保存增、删、改的内容,建议显示的标明writeback=True。 #七、代码示例 #1.创建一个shelf对象,直接使用open函数即可 importshelve s=shelve.open(test_shelf.db)# try: s[kk]={int:10,float:9.5,String:Sampledata} s[MM]=[1,2,3] finally: s.close() #2.如果想要再次访问这个shelf,只需要再次shelve.open()就可以了,然后我们可以像使用字典一样来使用这个shelf importshelve try: s=shelve.open(test_shelf.db) value=s[kk] print(value) finally: s.close() #3.对shelf对象,增、删、改操作 importshelve s=shelve.open(test_shelf.db,flag=w,writeback=True) try: #增加 s[QQQ]=2333 #删除 dels[MM] #修改 s[kk]={String:daydayup} finally: s.close() #注意:flag设置为‘r’-只读模式,当程序试图去修改一个以只读方式打开的DB时,将会抛一个访问错误的异常。异常的具体类型取决于anydbm这个模块在创建DB时所选用的DB。异常举例:anydbm.error:need‘c’or‘n’flagtoopennewdb #4.循环遍历shelf对象 importshelve s=shelve.open(test_shelf.db) try: #方法一: foritemins.items(): print(键[{}]=值[{}].format(item[0],s[item[0]])) #方法二: forkey,valueins.items(): print(key,value) finally: s.close() #5.备注一个错误: #open中的参数filename,起初认为需要手动新建一个.db,或者.dat的文件,目前电脑中无任何真正的数据库文件,所以采用了新建txt文件,修改后缀的方法创建.db,或者.dat的文件。 #解释器报错,提示内容为:"anydbm.error:dbtypecouldnotbedetermined", #原因是是filename已经存在,并且格式与shelve不符,所以提示“dbtypecouldnotbedetermined”。 #解决方法是,删除该文件。首次运行后会自动生成该filename文件。 #6.稍微复杂些的案例,实现一个简单提问式的数据库 #encoding:utf-8 #2018/3/8 #简单的数据库 importsys,shelve defprint_help(): 存储(增加)、查找、更新(修改)、循环打印、删除、退出、帮助 print(Theavailablecommonsare:) print(store:Storesinformationaboutaperson) print(lookup:LooksupapersonfromIDnumbers) print("update:UpdateapersonsinformationfromIDnumber") print(print_all:Printallinformations) print("delete:DeleteapersonsinformationfromIDnumber") print(quit:Savechangesandexit) print(?:Printthismessage) defstore_people(db): pid=input(PleaseenterauniqueIDnumber:) person={} person[name]=input(Pleaseenterthename:) person[age]=input(Pleaseentertheage:) person[phone]=input(Pleaseenterthephone:) db[pid]=person print("Storeinformation:pidis%s,informationis%s"%(pid,person)) deflookup_people(db): pid=input(Pleaseenterthenumber:) field=input(Whatwouldyouliketoknow?(name,age,phone)) ifpidindb.keys(): value=db[pid][field] print("Pid%ss%sis%s"%(pid,field,value)) else: print(Notfoundthisnumber) defupdate_people(db): pid=input(Pleaseenterthenumber:) field=input(Whatwouldyouliketoupdate?(name,age,phone)) newvalue=input(Enterthenewinformation:) ifpidindb.keys(): value=db[pid] value[field]=newvalue print("Pid%ss%supdateinformationis%s"%(pid,field,newvalue)) else: print("Notfoundthisnumber,cantupdate") defdelete_people(db): pid=input(Pleaseenterthenumber:) ifpidindb.keys(): deldb[pid] print("pid%ssinformationdeletedone"%pid) else: print("Notfoundthisnumber,cantdelete") defprint_all_people(db): print(Allinformationare:) forkey,valueindb.items(): print(key,value) defenter_cmd(): cmd=input(Pleaseenterthecmd(?forhelp):) cmd=cmd.strip().lower() returncmd defmain(): database=shelve.open(database201803.dat,writeback=True) try: whileTrue: cmd=enter_cmd() ifcmd==store: store_people(database) elifcmd==lookup: lookup_people(database) elifcmd==update: update_people(database) elifcmd==print_all: print_all_people(database) elifcmd==delete: delete_people(database) elifcmd==?: print_help() elifcmd==quit: return finally: database.close() if__name__==__main__: main() #shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写; #key必须为字符串,而值可以是python所支持的数据类型 #shelve模块(**)------可以当做数据库用,以后基本不会用,(可以很方面的往文件中写数据类型和读) importshelve#存取很方便(可以做一个简单的数据存储方案) f=shelve.open(rsheve.txt) f[stu1_info]={name:egon,age:18,hobby:[piao,smoking,drinking]}#存 f[stu2_info]={name:gangdan,age:53} f[school_info]={website:http://www.pypy.org,city:beijing} print(f[stu1_info][hobby]) f.close() importshelve d=shelve.open(ra.txt)#生成三个文件分别是:a.txt.bak\a.txt.dat\a.txt.dir d[tom]={age:18,sex:male}#存的时候会生成三个文件,不用管,是python的一种处理机制 print(d[tom][sex])#可以取出字典中的key对应的value print(d[tom])#取出tom对应的字典 d.close() importshelve d=shelve.open(ra.txt,writeback=True)#writeback=True,对子字典修改完后要写回,否则不会看到修改后的结果 d[egon]={age:18,sex:male}#存的时候会生成三个文件,不用管,是python的一种处理机制 d[egon][age]=20#将年龄修改为20 print(d[egon][age])#此时拿到的是修改后的年龄 print(d[egon][sex]) d.close()

本文内容总结:一、定义,二、用途,三、用法,四、关联模块Anydbm,五、方法,六、writeback参数,

原文链接:https://www.cnblogs.com/sui776265233/p/9225164.html