day5-shelve模塊


一、概述

前面章節我們講述了json和pickle模塊的序列化和反序列化處理,他們有一個不足是在python 3中不能多次dump和load,shelve模塊則可以規避這個問題。
shelve模塊是一個簡單的k,v將內存數據通過文件持久化的模塊,可以持久化任何pickle可支持的python數據格式,是pickle 更上一層的封裝。


二、shelve模塊的用法

Shelve模塊提供了基本的存儲操作,Shelve中的open函數在調用的時候返回一個shelf對象,通過該對象可以存儲內容,即像操作字典一樣進行存儲操作。當在該對象中查找元素時,對象會根據已經存儲的版本進行重新構建,當給某個鍵賦值的時候,元素會被存儲。

  • 持久化存儲
      1 import shelve
      2 
      3 def member_info(name, age):
      4     print("Member info:", name, age)
      5 
      6 name = ['Jack', 'Maxwell', 'Tom']
      7 info = {'name':'Maxwell', 'age':18}
      8 
      9 with shelve.open('shelve_demo') as data:
     10     data['name'] = name
     11     data['info'] = info
     12     data['func'] = member_info
    代碼執行后會生成三個文件:
    image
    其中shelve_demo.bak和shelve_demo.dir文件內容相同,顯示如下:
      1 'name', (0, 43)
      2 'info', (512, 45)
      3 'func', (1024, 27)
    shelve_demo.dat猜測為類數據庫文件把。
  • 解析文件內容
      1 import shelve
      2 
      3 def member_info(name, age):
      4     print("Member info:", name, age)
      5 
      6 with shelve.open('shelve_demo') as data:
      7     print(data['name'])    #這里的key與之前保存的文件內容里面的key完全對應,否則會報錯
      8     print(data['info'])
      9     print(data['func']('Alex', 22))
     10 
     11 #運行結果輸出:
     12 ['Jack', 'Maxwell', 'Tom']
     13 {'name': 'Maxwell', 'age': 18}
     14 Member info: Alex 22
     15 None
  • value值的修改
    一般情況下,我們通過shelve來open一個對象后,只能進行一次賦值處理,賦值后不能再次更新處理。
      1 import shelve
      2 
      3 def member_info(name, age):
      4     print("Member info:", name, age)
      5 
      6 name = ['Jack', 'Maxwell', 'Tom']
      7 info = {'name':'Maxwell', 'age':18}
      8 
      9 with shelve.open('shelve_demo') as data:
     10     data['name'] = name
     11     data['info'] = info
     12     data['name'].append('Alex')
     13     print(data['name'])
     14 
     15 程序輸出:
     16 ['Jack', 'Maxwell', 'Tom']  #第一次賦值后apend的元素並沒有生效
    再次open打開結果也是這樣:
      1 import shelve
      2 
      3 def member_info(name, age):
      4     print("Member info:", name, age)
      5 
      6 name = ['Jack', 'Maxwell', 'Tom']
      7 info = {'name':'Maxwell', 'age':18}
      8 
      9 
     10 with shelve.open('shelve_demo') as data:
     11     print(data['name'])
    造成上述情況的原因是:我們只是修改了shelve對象的副本,而它並木有被最終保存。此時我們除了下文要講述的update方法外,還有以下兩種方法:
    方法一: shelve open一個對象后,先用臨時變量指向對象副本,在臨時變量上修改后讓對象副本再次指向臨時變量,從而覆蓋保存對象副本。這種方法的本質是對open后的對象重新賦新值,並非在原有基礎上進行update,也就是open后的對象內存指向地址發生了變化。
      1 import shelve
      2 
      3 def member_info(name, age):
      4     print("Member info:", name, age)
      5 
      6 name = ['Jack', 'Maxwell', 'Tom']
      7 info = {'name':'Maxwell', 'age':18}
      8 
      9 with shelve.open('shelve_demo') as data:
     10     data['name'] = name
     11     data['info'] = info
     12     temp = data['name']  #這里的關鍵點在於對臨時變量的使用
     13     temp.append('Alex')
     14     data['name'] = temp
     15     print(data['name'])
     16 
     17 程序輸出:
     18 ['Jack', 'Maxwell', 'Tom', 'Alex']
    方法二:借助open的writeback=True參數來實現,默認情況下該參數的值為False。
      1 import shelve
      2 
      3 def member_info(name, age):
      4     print("Member info:", name, age)
      5 
      6 name = ['Jack', 'Maxwell', 'Tom']
      7 info = {'name':'Maxwell', 'age':18}
      8 
      9 with shelve.open('shelve_demo', writeback=True) as data:
     10     data['name'] = name
     11     data['info'] = info
     12     data['name'].append('Alex')
     13     print(data['name'])
     14 
     15 程序輸出:
     16 ['Jack', 'Maxwell', 'Tom', 'Alex']

  • update方法
    value值的更新還有一個update方法,使用起來也比較方便:
      1 import shelve
      2 
      3 def member_info(name, age):
      4     print("Member info:", name, age)
      5 
      6 name = ['Jack', 'Maxwell', 'Tom']
      7 info = {'name':'Maxwell', 'age':18}
      8 
      9 with shelve.open('shelve_demo', writeback=True) as data:
     10     data['name'] = name
     11     data['info'] = info
     12     data.update({'name':['Jack', 'Maxwell', 'Tom', 'Alex']})  #這里也是重新賦值
     13     print(data['name'])
     14 
     15 程序輸出:
     16 ['Jack', 'Maxwell', 'Tom', 'Alex']
    重新load一下看看結果:
      1 import shelve
      2 
      3 def member_info(name, age):
      4     print("Member info:", name, age)
      5 
      6 name = ['Jack', 'Maxwell', 'Tom']
      7 info = {'name':'Maxwell', 'age':18}
      8 
      9 
     10 with shelve.open('shelve_demo') as data:
     11     print(data['name'])
     12 
     13 程序輸出:
     14 ['Jack', 'Maxwell', 'Tom', 'Alex']
  • get方法
    通過shelve.open反序列化load對象到內存后,可以通過get方法來獲取key對應的value:
      1 __author__ = 'Maxwell'
      2 
      3 import shelve
      4 
      5 def member_info(name, age):
      6     print("Member info:", name, age)
      7 
      8 name = ['Jack', 'Maxwell', 'Tom']
      9 info = {'name':'Maxwell', 'age':18}
     10 
     11 
     12 with shelve.open('shelve_demo') as data:
     13     print(data.get('name'))
     14 
     15 程序輸出:
     16 ['Jack', 'Maxwell', 'Tom', 'Alex']

三、總結

shelve概念總結:

  • shelve模塊可以看做是pickle模塊的升級版,因為shelve使用的就是pickle的序列化協議,但是shelve比pickle提供的操作方式更加簡單、方便。
  • shelve模塊相對於其它兩個模塊在將Python數據持久化到本地磁盤時有一個很明顯的優點就是,它允許我們可以像操作dict一樣操作被序列化的數據,而不必一次性的保存或讀取所有數據。
  • shelve模塊持久化支持更多的python數據類型

使用建議:

  1. 需要與外部系統交互時用json模塊;
  2. 需要將少量、簡單Python數據持久化到本地磁盤文件時可以考慮用pickle模塊;
  3. 需要將大量Python數據持久化到本地磁盤文件或需要一些簡單的類似數據庫的增刪改查功能時,可以考慮用shelve模塊。

以上內容摘自大神博客http://www.cnblogs.com/yyds/p/6563608.html





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM