zoukankan      html  css  js  c++  java
  • python的pickle和shelve模块

    python中用于序列化的模块总结

     

    目录

    pickle模块

    shelve模块

    xml模块

     

     

     

    pickle模块

    介绍

    Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系,所以只用在数据存储上,但是json能做数据传输和存储。
    优点就是支持的数据类型多,能序列化函数、类。

      

    使用

    json会把数据转为字符串
    pickle会把数据转为字节类型的数据


    四个方法
    pickle.dumps()
    pickle.dump()
    pickle.load()
    pickle.load()
    四个方法的使用方法和json模块一样
    具体可以结合json模块一起学习
    https://www.cnblogs.com/-wenli/p/10187130.html
    #存储数据

    import pickle dic={'name':'linlin','age':18} data1 = pickle.dumps(dic) #序列化 f = open('file1','wb') #存储 f.write(data1) f.close()

    运行结果:

    可以看到存储到文件的数据,我们是看不懂的,不同于json

    #读取数据

    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模块

    shelve类似于一个存储持久化对象的持久化字典,即字典文件。
    
    使用方法也类似于字典。

    shelve模块可以当成一个轻量的数据库db,将数据以字典的类型(key,value)通过文件持久化,模拟出简单的db效果。

      

    存储数据

    注意:shelve模块有个限制,它不支持多个应用同一时间往同一个DB(文件)进行写操作。

    import shelve
    db1 = shelve.open('file') #打开一个文件
    db1['dic'] = {'int':12, 'float':2.5, 'string':'shelve db'} 
    #这里dic为key,key必须为字符串,而值可以是python所支持的数据类型 #直接对文件句柄[key]操作,就可以存入数据 db1.close()
    且重要的是它还会直接在打开的当前目录生成三个文件:
    file.bak
    file.dat
    file.dir
    其中shelve.db1.dat 存储的就是b字节数据类型的数据, bak和dir后缀的就可能是和数据库相关的设计缓存之类的东西。

      

    读取数据

    注意:取出数据的时候也只需要直接用字典的操作方法获取即可,但是如果key不存在会报错

    import shelve
    f = shelve.open('file') #打开一个文件

    #第一种方式
    print(f.get('dic')['int']) #12
    print(f.get('dic')['float']) #2.5
    print(f.get('dic')['string']) #shelve db


    #第二种方式
    print(f['dic']['int'])#12
    print(f['dic']['float']) #2.5

    print(f['dic']['string']) #shelve db

    修改数据

    由于shelve在默认情况下是不会记录对持久化对象(字典下的键的值-条目)做出修改的,
    所以在shelve.open()时候需要修改默认参数writeback=True,
    否则对象的条目修改不会'拷贝回写'来进行保存。

    当试图让shelve去自动捕获对象的变化时,应当在打开shelf的时候将writeback设置为True。
    而将writeback这个flag设置为True以后,shelf将会将所有从DB中读取的对象存放到一个内存缓存。
    当close() shelf的时候,缓存中所有的对象会被重新写入DB。

    #第一种方法
    #修改键值
    import shelve f = shelve.open('file',writeback=True) #打开一个文件 data=f['dic']['int'] data = 10 f.close() #这里一定要关闭文件,才能读取到修改后的值 print(data) #10



    #添加列表值
    import shelve
    list1 = ['tie', 'le', 'yu']
    # 既然最终生成的文件会是dat格式的,何不一开始就指定后缀是dat
    db2 = shelve.open('shelve_db2.dat')
    db2['lis'] = list1
    # 文件句柄是通过字典的操作方式去拿里面的键值对,lis这个键对应的值是一个列表
    db2['lis'].append('mao')
    # 而此列表增加一个字符串元素后再打印,感觉不出有发生增加的变化
    print(type(db2['lis']), db2['lis'])
    # 返回列表:['tie', 'le', 'yu']
    #这里返回的结果没有'mao',因为没有写回。
    #第二种方法
    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'}

      

    总结

    第一种方法shelve会将所有从DB中读取的对象存放到一个内存缓存,当close() shelf的时候,缓存中所有的对象会被重新写入DB,所以一定要关闭文件,重新读取才能生效
    
    

      

    writeback方式有优点也有缺点
    
    优点是减少了我们出错的概率,且让对象的持久化对用户更加的透明了
    但这种方式并不是所有的情况下都需要
    首先,使用writeback以后,shelf在open()的时候会增加额外的内存消耗
    并且当DB在close()的时候会将缓存中的每一个对象都写入到DB,这也会带来额外的等待时间
    因为shelve没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入
    

      

    第二种方法通过中间变量实现了修改,这种属于直接赋值和拷贝写回无关,会生效,新值覆盖旧值
    
    所以我们一定要弄明白一件事情
    从shelve的db文件中重新再访问一个key拿的是它的拷贝
    修改此拷贝后不做拷贝写回并不影响原来的key
    但你要是直接做的操作是赋值新的值到一个key里,那肯定就是指向原来的key,会被覆盖的
    而这种赋值覆盖对于shelve来说这是一个正常的行为阿
    和键中的值看起来不能被修改一事并不矛盾
    

      

  • 相关阅读:
    详解GaussDB(for MySQL)服务:复制策略与可用性分析
    华为云的研究成果又双叒叕被MICCAI收录了!
    充分释放数据价值:安全、可信6到飞起
    未来云原生世界的“领头羊”:容器批量计算项目Volcano 1.0版本发布
    一文带你掌握OBS的两种常见的鉴权方式
    数据库实践丨MySQL多表join分析
    技术贴丨教你使用华为云鲲鹏服务器部署Discuz!论坛
    python Scrapy 从零开始学习笔记(二)
    python Scrapy 从零开始学习笔记(一)
    从零开始学Electron笔记(七)
  • 原文地址:https://www.cnblogs.com/-wenli/p/10198014.html
Copyright © 2011-2022 走看看