python的pickle和shelve模块
python中用于序列化的模块总结
目录
pickle模块
shelve模块
xml模块
pickle模块
介绍
1 | Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系,所以只用在数据存储上,但是json能做数据传输和存储。<br>优点就是支持的数据类型多,能序列化函数、类。 |
使用
1 2 | json会把数据转为字符串 pickle会把数据转为字节类型的数据<br><br><br>四个方法<br>pickle.dumps() <br>pickle.dump()<br>pickle.load()<br>pickle.load()<br>四个方法的使用方法和json模块一样<br>具体可以结合json模块一起学习<br><a href= "https://www.cnblogs.com/-wenli/p/10187130.html" target= "_blank" >https://www.cnblogs.com/-wenli/p/10187130.html</a> |
1 2 3 4 5 6 7 8 9 10 11 | #存储数据<br><br>import pickle dic={ 'name' : 'linlin' , 'age' :18} data1 = pickle.dumps(dic) #序列化 f = open( 'file1' , 'wb' ) #存储 f.write(data1) f.close() |
运行结果:
可以看到存储到文件的数据,我们是看不懂的,不同于json
1 2 3 4 5 6 7 8 9 | #读取数据<br><br>import pickle f = open( 'file1' , 'rb' ) data2=f.read() data2=pickle.loads(data2)#反序列化 print (data2) key_value=data2[ 'name' ] print (key_value) f.close() |
运行结果:
shelve模块
1 2 3 | shelve类似于一个存储持久化对象的持久化字典,即字典文件。 使用方法也类似于字典。<br><br>shelve模块可以当成一个轻量的数据库db,将数据以字典的类型(key,value)通过文件持久化,模拟出简单的db效果。 |
存储数据
注意:shelve模块有个限制,它不支持多个应用同一时间往同一个DB(文件)进行写操作。
1 2 3 4 5 | import shelve db1 = shelve.open( 'file' ) #打开一个文件 db1[ 'dic' ] = { 'int' :12, 'float' :2.5, 'string' : 'shelve db' } <br>#这里dic为key,key必须为字符串,而值可以是python所支持的数据类型 #直接对文件句柄[key]操作,就可以存入数据 db1.close() |
1 2 3 4 | 且重要的是它还会直接在打开的当前目录生成三个文件: file.bak file.dat file.dir<br>其中shelve.db1.dat 存储的就是b字节数据类型的数据, bak和dir后缀的就可能是和数据库相关的设计缓存之类的东西。 |
读取数据
注意:取出数据的时候也只需要直接用字典的操作方法获取即可,但是如果key不存在会报错
1 2 | import shelve f = shelve.open( 'file' ) #打开一个文件<br><br>#第一种方式<br> print (f.get( 'dic' )[ 'int' ]) #12print(f.get( 'dic' )[ 'float' ]) #2.5print(f.get( 'dic' )[ 'string' ]) #shelve db<br><br><br>#第二种方式 print (f[ 'dic' ][ 'int' ])#12print(f[ 'dic' ][ 'float' ]) #2.5<br><br> print (f[ 'dic' ][ 'string' ]) #shelve db |
修改数据
1 2 3 | 由于shelve在默认情况下是不会记录对持久化对象(字典下的键的值-条目)做出修改的, 所以在shelve.open()时候需要修改默认参数writeback=True, 否则对象的条目修改不会 '拷贝回写' 来进行保存。<br><br>当试图让shelve去自动捕获对象的变化时,应当在打开shelf的时候将writeback设置为True。<br>而将writeback这个flag设置为True以后,shelf将会将所有从DB中读取的对象存放到一个内存缓存。<br>当close() shelf的时候,缓存中所有的对象会被重新写入DB。<br><br> |
1 2 3 4 5 6 7 | #第一种方法<br>#修改键值<br>import shelve f = shelve.open( 'file' ,writeback=True) #打开一个文件 data=f[ 'dic' ][ 'int' ] data = 10 f.close() #这里一定要关闭文件,才能读取到修改后的值 print (data) #10<br><br><br><br>#添加列表值import shelve<br>list1 = [ 'tie' , 'le' , 'yu' ]<br># 既然最终生成的文件会是dat格式的,何不一开始就指定后缀是dat<br>db2 = shelve.open( 'shelve_db2.dat' )<br>db2[ 'lis' ] = list1<br># 文件句柄是通过字典的操作方式去拿里面的键值对,lis这个键对应的值是一个列表<br>db2[ 'lis' ].append( 'mao' )<br># 而此列表增加一个字符串元素后再打印,感觉不出有发生增加的变化<br> print (type(db2[ 'lis' ]), db2[ 'lis' ])<br># 返回列表:[ 'tie' , 'le' , 'yu' ]<br>#这里返回的结果没有 'mao' ,因为没有写回。 |
1 2 3 4 5 6 | #第二种方法<br>import shelve f = shelve.open( 'file' ) #打开一个文件 temp=f[ 'dic' ] #从文件中读取之前存储的对象 temp[ 'int' ]=12 #直接对对象进行修改 f[ 'dic' ]=temp #重新存储至字典文件对象中 print (f[ 'dic' ]) #{ 'int' : 12, 'float' : 2.5, 'string' : 'shelve db' } |
总结
1 | 第一种方法shelve会将所有从DB中读取的对象存放到一个内存缓存,当close() shelf的时候,缓存中所有的对象会被重新写入DB,所以一定要关闭文件,重新读取才能生效 |
1 2 3 4 5 6 7 | writeback方式有优点也有缺点 优点是减少了我们出错的概率,且让对象的持久化对用户更加的透明了 但这种方式并不是所有的情况下都需要 首先,使用writeback以后,shelf在open()的时候会增加额外的内存消耗 并且当DB在close()的时候会将缓存中的每一个对象都写入到DB,这也会带来额外的等待时间 因为shelve没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入 |
1 | 第二种方法通过中间变量实现了修改,这种属于直接赋值和拷贝写回无关,会生效,新值覆盖旧值 |
1 2 3 4 5 6 | 所以我们一定要弄明白一件事情 从shelve的db文件中重新再访问一个key拿的是它的拷贝 修改此拷贝后不做拷贝写回并不影响原来的key 但你要是直接做的操作是赋值新的值到一个key里,那肯定就是指向原来的key,会被覆盖的 而这种赋值覆盖对于shelve来说这是一个正常的行为阿 和键中的值看起来不能被修改一事并不矛盾 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?