Python之序列化模塊
阿新 • • 發佈:2018-10-11
pytho 反序列化 同一時間 this 方法 字典 並不是 設置 字典類
序列化模塊
導入:import module
序列化:數據類型和str之間的轉換,數據持久化(存儲),網絡交互(傳輸)本質:將程序中的數據類型轉成str
反序列化:將字符串轉換為其本來的數據類型
序列化和反序列化這些操作都是一次性的,一次轉換,一次還原
(1) json (存文件,網絡傳輸)
json模塊只給我們提供了四個功能:
序列化:dump,dumps
反序列化:load, loads
dumps和loads:對數據類型進行序列化和反序列化
1 import json 2 3 dic = {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, ‘k3‘: ‘v3‘} 4 5 # 序列化:將一個字典轉換成一個字符串 6 str_dic = json.dumps(dic) 7 8 print(type(str_dic), str_dic) 9 # 結果: 10 # 註意,json轉換完的字符串類型的字典中的字符串是由""表示的 11 # <class ‘str‘> {"k3": "v3", "k1": "v1", "k2": "v2"} 12 13 14 # 反序列化:將一個字符串格式的字典轉換成一個字典 15 # 註意,要用json的loads功能處理的字符串類型的字典中的字符串必須由""表示 16dic2 = json.loads(str_dic) 17 18 print(type(dic2), dic2) 19 # 結果: 20 # <class ‘dict‘> {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, ‘k3‘: ‘v3‘} 21 22 list_dic = [1, [‘a‘, ‘b‘, ‘c‘], 3, {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘}] 23 str_dic = json.dumps(list_dic) # ps:也可以處理嵌套的數據類型 24 print(type(str_dic), str_dic) 25 # 結果: 26# <class ‘str‘> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}] 27 28 list_dic2 = json.loads(str_dic) 29 print(type(list_dic2), list_dic2) 30 # 結果: 31 # <class ‘list‘> [1, [‘a‘, ‘b‘, ‘c‘], 3, {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘}]
dump和load:對文件句柄進行序列化和反序列化
1 import json 2 3 f = open(‘json_file‘, ‘w‘) 4 dic = {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, ‘k3‘: ‘v3‘} 5 6 # dump方法接收一個文件句柄,直接將字典轉換成json字符串寫入文件 7 json.dump(dic, f) 8 f.close() 9 10 f = open(‘json_file‘) 11 12 # load方法接收一個文件句柄,直接將文件中的json字符串轉換成數據結構返回 13 dic2 = json.load(f) 14 f.close() 15 print(type(dic2), dic2)
ensure_ascii關鍵字:默認是True,表示按照ascii的形式顯示,設置為False的時候,表是按照原來的文本樣式顯示(主要針對中文)
1 import json 2 3 f = open(‘file‘, ‘w‘) 4 json.dump({‘國籍‘: ‘中國‘}, f) 5 ret = json.dumps({‘國籍‘: ‘中國‘}) 6 f.write(ret + ‘\n‘) 7 json.dump({‘國籍‘: ‘美國‘}, f, ensure_ascii=False) 8 ret = json.dumps({‘國籍‘: ‘美國‘}, ensure_ascii=False) 9 f.write(ret + ‘\n‘) 10 f.close() 11 12 # 寫到文件中的結果: 13 # {"\u56fd\u7c4d": "\u4e2d\u56fd"}{"\u56fd\u7c4d": "\u4e2d\u56fd"} 14 # {"????": "????"}{"????": "????"}(這裏是因為文件打開的模式不對)
(2) pickle 模塊
pickle模塊提供了四個功能:dumps、dump(序列化,存)、loads(反序列化,讀)、load
(不僅可以序列化字典,列表...可以把python中任意的數據類型序列化)
pickle,用於python特有的類型 和 python的數據類型間進行轉換
pickle--只能寫進去,不能追加
示例1:
1 import pickle 2 3 dic = {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, ‘k3‘: ‘v3‘} 4 str_dic = pickle.dumps(dic) 5 print(str_dic) # 一串二進制內容 6 7 dic2 = pickle.loads(str_dic) 8 print(dic2) # 字典 9 10 # 結果: 11 # b‘\x80\x03}q\x00(X\x02\x00\x00\x00k1q\x01X\x02\x00\x00\x00v1q\x02X\x02\x00\x00\x00k2q\x03X\x02\x00\x00\x00v2q\x04X\x02\x00\x00\x00k3q\x05X\x02\x00\x00\x00v3q\x06u.‘ 12 # {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, ‘k3‘: ‘v3‘}
示例2:
1 import time 2 import pickle 3 4 struct_time = time.localtime(1000000000) 5 print(struct_time) 6 7 f = open(‘pickle_file‘, ‘wb‘) 8 pickle.dump(struct_time, f) 9 f.close() 10 11 f = open(‘pickle_file‘, ‘rb‘) 12 struct_time2 = pickle.load(f) 13 f.close() 14 15 print(struct_time2.tm_year) 16 17 18 # 結果: 19 # time.struct_time(tm_year=2001, tm_mon=9, tm_mday=9, tm_hour=9, tm_min=46, tm_sec=40, tm_wday=6, tm_yday=252, tm_isdst=0) 20 # 2001
json和pickle模塊對比:
json,用於字符串 和 python數據類型間進行轉換
pickle,用於python特有的類型 和 python的數據類型間進行轉換(可以把python中任意的數據類型序列化)
json--能處理的很少
pickle--可以序列化python裏沒有的,自己定義的數據類型
json---是所有p編程語言通用的一種數據類型---網絡編程
pickle---可以序列化一些自定義的數據類型---遊戲
(3)shelve---只提供了open 方法
shelve也是python提供給我們的序列化工具,比pickle用起來更簡單一些。
shelve只提供給我們一個open方法,是用key來訪問的,使用起來和字典類似。
1 import shelve 2 3 f = shelve.open(‘shelve_file‘) 4 f[‘key‘] = {‘int‘: 10, ‘float‘: 9.5, ‘string‘: ‘Sample data‘} # 直接對文件句柄操作,就可以存入數據 5 f.close() 6 7 import shelve 8 9 f1 = shelve.open(‘shelve_file‘) 10 existing = f1[‘key‘] # 取出數據的時候也只需要直接用key獲取即可,但是如果key不存在會報錯 11 f1.close() 12 print(existing) 13 14 # 結果: 15 # {‘int‘: 10, ‘float‘: 9.5, ‘string‘: ‘Sample data‘}
這個模塊有個限制,它不支持多個應用同一時間往同一個DB進行寫操作。
所以當我們知道我們的應用如果只進行讀操作,可以讓shelve通過只讀方式打開DB
1 import shelve 2 3 f = shelve.open(‘shelve_file‘, flag=‘r‘) 4 existing = f[‘key‘] 5 f.close() 6 print(existing)
由於shelve在默認情況下是不會記錄待持久化對象的任何修改的,所以我們在shelve.open()時候需要修改默認參數,否則對象的修改不會保存。
1 import shelve 2 f1 = shelve.open(‘shelve_file‘) 3 print(f1[‘key‘]) 4 f1[‘key‘][‘new_value‘] = ‘this was not here before‘ 5 f1.close() 6 7 f2 = shelve.open(‘shelve_file‘, writeback=True) 8 print(f2[‘key‘]) 9 f2[‘key‘][‘new_value‘] = ‘this was not here before‘ 10 f2.close()
writeback方式有優點也有缺點。優點是減少了我們出錯的概率,並且讓對象的持久化對用戶更加的透明了;
但這種方式並不是所有的情況下都需要,
首先,使用writeback以後,shelf在open()的時候會增加額外的內存消耗,並且當DB在close()的時候會將緩存中的每一個對象都寫入到DB,這也會帶來額外的等待時間。
因為shelve沒有辦法知道緩存中哪些對象修改了,哪些對象沒有修改,因此所有的對象都會被寫入
Python之序列化模塊