json模塊 JSON (JavaScript Object Notation):是一個輕量級的數據交換格式模塊,受javascript對象文本語法啟發,但不屬於JavaScript的子集。 常用方法: dump(obj,fp):將對象以字元串的形式寫入文件中。 load(fp):將數據從文件中讀出 ...
json模塊
JSON (JavaScript Object Notation):是一個輕量級的數據交換格式模塊,受javascript對象文本語法啟發,但不屬於JavaScript的子集。
常用方法:
dump(obj,fp):將對象以字元串的形式寫入文件中。
load(fp):將數據從文件中讀出,並返回(需要變數接收)。
dumps(obj):將對象轉換成json字元串形式。
loads(str):將json字元串數據轉換成原來的數據類型。
實例如下:dumps(obj) | loads(str)
import json dict_1 = {"電影":"黃飛鴻","電視劇":"霍元甲"} json_str = json.dumps(dict_1) # 將字典轉換成json的字元串類型 dict_2 = json.loads(json_str) # 將json的字元串類型轉換成原數據 print(json_str,type(json_str)) print(dict_2.items(),type(dict_2)) # 列印內容如下 {"\u7535\u5f71": "\u9ec4\u98de\u9e3f", "\u7535\u89c6\u5267": "\u970d\u5143\u7532"} <class 'str'> dict_items([('電影', '黃飛鴻'), ('電視劇', '霍元甲')]) <class 'dict'>
實例如下:dump(obj,fp) | load(fp)
import json # 向文件中寫入json數據 dict_1 = {"電影":"黃飛鴻","電視劇":"霍元甲"} file_write = open("json.txt",mode="w",encoding="utf-8") json.dump(dict_1,file_write) # 將字典以json的字元串類型寫入文件 file_write.close() # 從文件中讀取json數據 file_read = open("json.txt",mode="r",encoding="utf-8") dict_2 = json.load(file_read) # 將文件中內容轉換成原數據類型並返回 file_read.close() print(dict_2.items(),type(dict_2)) # 列印轉換後的數據 # 列印內容如下 dict_items([('電影', '黃飛鴻'), ('電視劇', '霍元甲')]) <class 'dict'>
這裡需要註意的是json模塊dump(obj,fp)雖然可以多次上傳,但是在load時會報錯,load(fp)函數不能轉換多次dump的數據。所以如果想要向json文件中新增數據時,需要將數據load下來轉換成原數據,然後在原數據基礎上進行新增。最後將處理後的數據dump到文件中。
pickle模塊:
屬於python專有的模塊,用法,功能與json類似。
常用方法:
dump(obj,fp):將對象以字元串的形式寫入文件中。
load(fp):將數據從文件中讀出,並返回(需要變數接收)。
dumps(obj):將對象轉換成json字元串形式。
loads(str):將json字元串數據轉換成原來的數據類型。
dump(obj,fp) | load(fp) 示例如下;
import pickle # 將數據以json方式寫入文件 dict_1 = {"電影":"黃飛鴻","電視劇":"霍元甲"} file_write = open("pickle.txt",mode="wb") pickle.dump(dict_1,file_write) # 將字典以位元組的形式寫入文件 file_write.close() # 從文件中以json方式讀取數據 file_read = open("pickle.txt",mode="rb") dict_2 = pickle.load(file_read) # 將文件中內容轉換成原數據類型並返回 file_read.close() print(dict_2.items(),type(dict_2)) # 列印轉換後的數據 # 列印內容如下 dict_items([('電影', '黃飛鴻'), ('電視劇', '霍元甲')]) <class 'dict'>
dumps(obj) | loads(obj) 示例如下;
import pickle dict_1 = {"電影":"黃飛鴻"} pickle_byte = pickle.dumps(dict_1) # 將字典轉換成pickle位元組 print(pickle_byte) # 將pickle位元組轉換成原數據 dict_2 = pickle.loads(pickle_byte) print(dict_2.items(),type(dict_2)) # 列印轉換後的數據 # 列印內容如下 b'\x80\x03}q\x00X\x06\x00\x00\x00\xe7\x94\xb5\xe5\xbd\xb1q\x01X\t\x00\x00\x00\xe9\xbb\x84\xe9\xa3\x9e\xe9\xb8\xbfq\x02s.' dict_items([('電影', '黃飛鴻')]) <class 'dict'>
與json不同的是pickle可以多次dump多次load,如下:
import pickle dict_1 = {"電影":"黃飛鴻"} dict_3 = {"電視劇":"霍元甲"} dict_5 = {"動畫片":"葫蘆娃"} file_write = open("pickle.txt",mode="wb") pickle.dump(dict_1,file_write) # 將dict_1以位元組的形式寫入文件 pickle.dump(dict_3,file_write) # 將dict_3以位元組的形式寫入文件 pickle.dump(dict_5,file_write) # 將dict_5以位元組的形式寫入文件 file_write.close() file_read = open("pickle.txt",mode="rb") dict_2 = pickle.load(file_read) # 將文件中內容轉換成原數據類型並返回 dict_4 = pickle.load(file_read) # 將文件中內容轉換成原數據類型並返回 dict_6 = pickle.load(file_read) # 將文件中內容轉換成原數據類型並返回 file_read.close() print(dict_2.items(),type(dict_2)) # 列印轉換後的數據 print(dict_4.items(),type(dict_4)) # 列印轉換後的數據 print(dict_6.items(),type(dict_4)) # 列印轉換後的數據 # 列印內容如下 dict_items([('電影', '黃飛鴻')]) <class 'dict'> dict_items([('電視劇', '霍元甲')]) <class 'dict'> dict_items([('動畫片', '葫蘆娃')]) <class 'dict'>
小結:
1、json屬於通用的模塊,Java,JS等其它語言也支持。
pickle是Python私有的,只支持Python。
2、json將對象轉換成json字元串類型。
pickle將對象轉換成pickle位元組類型。
3、json只能轉換dict,list,tuple,str,int,float,bool值等簡單數據類型
pickle能轉換除了lamda以外的所有已知數據類型。
4、json雖然可以多次dump但是load會報錯(這是最大的傷)。
pickle可以多次dump,多次load。
shelve模塊
使用json或者pickle持久化數據,能dump多次,但load的話只能取到最新的dump, 因為先前的數據已經被後面dump的數據覆蓋掉了。如果想要實現dump多次不被覆蓋,就可以想到使用shelve模塊。shelve模塊可以持久化所有pickle所支持的數據類型。另外,寫程式的時候如果不想用關係資料庫那種重量級的去存儲數據,也可以用到shelve。
shelve是用key來訪問的,使用起來和字典類似。 要註意的是,在shelve模塊中,key必須為字元串,而值可以是python所支持的數據類型。
另外,shelve其實用anydbm去創建DB並且管理持久化對象的。
shelve只提供給我們一個open方法,是用key來訪問的,使用起來和字典類似。 可以像字典一樣使用get來獲取數據等。
如下操作:
import shelve f_shelve = shelve.open('shelve') # 創建一個文件句柄 f_shelve["name"] = "小明" # 向文件中存放數據 f_shelve["age"] = 21 # 向文件中存放數據 f_shelve["sex"] = "男"
運行後會生成3個文件:shelve.bak shelve.dat shelve.dir
shelve.dat 存儲的就是b位元組數據類型的數據。bak和dir尾碼從字面上看是備份和目錄,具體做什麼的不是很清楚。
當我們寫好數據後,如何讀取呢?
import shelve f_shelve = shelve.open('shelve') # 創建一個文件句柄 # 列印文件內容,和類型 print(f_shelve["name"],f_shelve["age"],f_shelve["sex"],type(f_shelve)) # 列印內容如下 小明 21 男 <class 'shelve.DbfilenameShelf'>
既然f_shelve類似於字典,那我們也可以使用for迴圈進行列印,如下:
import shelve f_shelve = shelve.open('shelve') # 創建一個文件句柄 # 使用for迴圈列印內容 for k,v in f_shelve.items(): print(k,v) # 列印內容如下 name 小明 age 21 sex 男
f_shelve現在是一個特殊的文件句柄,它可以執行字典的多數方法,對文件里的數據進行操作。
import shelve f_shelve = shelve.open('shelve') # 創建一個文件句柄 f_shelve["list"] = [1,2,3] # 向文件中添加數據列表 f_shelve["list"].append("abc") # 向列表中追加內容. f_shelve["list"].pop(1) # 從列表中刪除一個元素 f_shelve["name"] = "小明" # 向文件中追加內容 f_shelve["name"] = "小紅" # 修改name所對應的值 print(f_shelve["list"],f_shelve["name"],sep="\n") # 列印內容如下 [1, 2, 3] 小紅
通過上面的列印內容我們可以發現,我們將列表寫入文件後,然後在讀取出來進行追加和刪除元素,並沒有對文件產生影響,文件中的列表內容還是原來的值。而我們向文件中添加字元串時,在讀取出來對字元串進行修改發現數據被修改了。
由此我們可以知道在向文件中寫入一個可變的數據時,如果讀取出來對數據進行修改只是在記憶體中的修改,修改後的數據並沒有被真正寫入到文件中。那麼我們該如何進行操作呢?這時就需要回寫了。
import shelve # 創建一個特殊的文件句柄,並添加回寫功能 f_shelve = shelve.open('shelve',writeback=True) f_shelve["list"] = [1,2,3] # 向文件中添加數據列表 f_shelve["list"].append("abc") # 向列表中追加內容. f_shelve["list"].pop(1) # 從列表中刪除一個元素 print(f_shelve["list"]) # 列印內容如下 [1, 3, 'abc']
這回我們在修改列表時,可以看出列表的數據確實被修改了。
總結如下:
1、shelve模塊將記憶體數據以字典的類型(key,value)通過文件持久化,模擬出簡單的db效果。
2、shelve模塊可以持久化任何pickle所支持的python數據格式,但是它的key必需得是字元串。
3、shelve可以看作是pickle模塊的一個封裝,但它實現了可以多次dump(後面的dump不會覆蓋前面的)和多次load。
4、shelve訪問己有key時,實際上取出的是數據源給出的一份拷貝,所以對於拷貝做出的增加和刪除等操作都需要用writeback=True參數才能實現寫入迴文件中進行修改。
5、shelve對於d[key] = data這種操作,視為存儲數據,無則新增,有則覆蓋,
對與訪問key當中的值(條目)進行修改,預設不回寫並不矛盾和衝突。