python摸爬滾打之day022----模組(序列化操作)
阿新 • • 發佈:2018-11-15
1、pickle
可以將我們python中的任意資料型別轉化成bytes並寫入到檔案中. 同樣也可以把檔案中寫好的bytes轉換回我們python的資料.
pickle可以直接序列化物件.
1 class Fruit: 2 def __init__(self,name,color): 3 self.name = name 4 self.color = color 5 6 def eat(self): 7 return "haochi" 8 9pickle序列化物件p1 = Fruit("apple1","red1") 10 p2 = Fruit("apple2","red4") 11 p3 = Fruit("apple3","red2") 12 p4 = Fruit("apple4","red6") 13 lst = [p1,p2,p3,p4] 14 15 pickle.dump(lst,open("fruit_info","wb")) 16 17 lst = pickle.load(open("fruit_info","rb")) 18 for i in lst: 19 print(i.name)
2、shelve
shelve提供python的持久化操作. 什麼叫持久化操作呢? 說白話,就是把資料寫到硬碟上. 在操作shelve的時候非常的像操作一個字典. 這個東西到後期. 就像redis差不多.
1 # shelve 資料的持久化操作, 像操作字典一樣去操作shelve ----------------------------------------------------------------- 2 d = shelve.open("shelve_file") 3 d["wlh"] = "王力巨集" 4 d["ljj"shelve] = {"name":"林俊杰","id":"singer"} 5 d["zj"] = {"name":"張傑","wife":{"name":"謝娜","gender":"女","worke":"大本營"}} 6 d.close() 7 8 9 d = shelve.open("shelve_file") 10 d.pop("zj") # 能刪除,但是再查詢時會報錯. 11 d.close() 12 13 14 d = shelve.open("shelve_file",writeback=True) # 如果是巢狀字典的話, 必須得加上writeback回寫引數, 不然沒法修改 15 d["ljj"]["id"] = "歌手" 16 print(d["ljj"]["id"]) 17 d.close()
3、configparser
該模組適用於配置檔案的格式與windows ini檔案類似,可以包含一個或多個節(section), 每個節可以有多個引數(鍵=值)
1 import configparser 2 config = configparser.ConfigParser() 3 config["DEFAULT"] = { # DEFAULT 是預設配置, 下面的一些子配置都會帶上DEFAULT 裡面的配置. 4 "預設設定1":"...1", 5 "預設設定2":"....2", 6 "預設設定3":".....3", 7 } 8 config["配置11"] = { 9 "設定11":"11", 10 "設定12":"12", 11 "設定13":"13", 12 } 13 config["配置22"] = { 14 "設定21":"21", 15 "設定22":"22", 16 "設定23":"23", 17 } 18 config["配置33"] = { 19 "設定31":"31", 20 "設定32":"32", 21 "設定33":"33", 22 } 23 24 with open("peizhi.ini","w",encoding="utf8") as f: 25 config.write(f) # 這裡的write()方法是configparser自己重新寫的,不是呼叫的檔案操作的write() 26 27 # 查 28 config = configparser.ConfigParser() 29 config.read("peizhi.ini",encoding="utf8") 30 print(config.sections()) # ['配置11', '配置22', '配置33'] 31 print(config["配置33"]["設定33"]) # 33 32 33 # 新增一個章節 先讀取檔案, 再修改, 最後寫入檔案 34 config = configparser.ConfigParser() 35 config.read("peizhi.ini",encoding="utf8") 36 config.add_section("配置44") 37 config["配置44"] = { 38 "設定41": "41", 39 "設定42": "42", 40 "設定43": "43", 41 } 42 config.write(open("peizhi.ini","w",encoding="utf8")) 43 44 # 修改章節 45 config = configparser.ConfigParser() 46 config.read("peizhi.ini",encoding="utf8") 47 config.set("配置44","設定43","443") 48 config.write(open("peizhi.ini","w",encoding="utf8")) 49 50 # 刪除章節或 章節元素 51 config = configparser.ConfigParser() 52 config.read("peizhi.ini",encoding="utf8") 53 config.remove_section("配置44") # 刪除"配置44"章節 54 config.remove_option("配置44","設定43") # 刪除"配置44"裡的"設定43"元素 55 config.write(open("peizhi.ini","w",encoding="utf8")) 56 57 # 對config的所有修改操作都是先建立config物件,然後用config讀取內容, 修改完之後再將config寫進檔案.configparser
4、json
json是所有語言都通用的模組
4.1 json和pickle的比較?
1 dic = {1:"青銅",2:"白銀",3:"黃金",4:"鉑金",5:"鑽石"} 2 3 ret = json.dumps(dic,ensure_ascii=False) # 用 ensure_ascii=False 來處理非中文顯示 4 print(ret,type(ret)) # json結果是 str 型別 5 # ret = pickle.dumps(dic) 6 # print(ret,type(ret)) # pickle結果是 bytes 型別View Code
4.2 json寫進檔案
1 dic = {'王力巨集':{"ji":"新加坡","gender":"男","album":"蓋世英雄"}, 2 "林俊杰":"愛笑的眼睛", 3 "張靚穎":{"gender":"女","album":"如果這就是愛情"}, 4 "張傑":"雲中的angle" 5 } 6 with open("singer_info.json","w",encoding="utf8") as f: 7 json.dump(dic,f,ensure_ascii=False,indent=4) # indent=4 即在json檔案中改成好看點的格式 8 # 即下面格式: 9 # { 10 # "王力巨集": { 11 # "ji": "新加坡", 12 # "gender": "男", 13 # "album": "蓋世英雄" 14 # }, 15 # "林俊杰": "愛笑的眼睛", 16 # "張靚穎": { 17 # "gender": "女", 18 # "album": "如果這就是愛情" 19 # }, 20 # "張傑": "雲中的angle" 21 # }json資料寫進檔案
4.3 json也能處理物件, 也能將物件寫進檔案(通過間接方式將物件轉成字典的形式,然後序列化字典寫進檔案)
1 class Fruit: 2 def __init__(self,name,color): 3 self.name = name 4 self.color = color 5 6 7 8 9 def trans1(obj): 10 return { 11 "name": obj.name, 12 "color": obj.color, 13 } 14 # 用json序列化物件 ??? 15 ap = Fruit("蘋果","紅色") 16 17 # 方法一: __dict__ 對obj的各種封裝資訊(也是字典)進行序列化 18 # ret = json.dumps(ap.__dict__, ensure_ascii=False) 19 # print(ret) 20 21 # 方法二: 對函式返回的結果進行序列化 22 ret = json.dumps(ap,default=trans1,ensure_ascii=False) # 把obj物件作為引數傳進trans裡,將返回的字典結果進行序列化 23 print(ret)json序列化物件
1 class Fruit: 2 def __init__(self,name,color): 3 self.name = name 4 self.color = color 5 6 7 def trans2(dic): 8 print(type(dic)) 9 return Fruit(dic["name"],dic["color"]) # 返回自己構造的Fruit物件 10 11 12 # 用json反序列化 13 s = '{"name": "蘋果", "color": "紅色"}' 14 ap = json.loads(s,object_hook=trans2) # 先將s進行反序列化, 然後將反序列化結果作為引數傳進trans2 ,在函式裡自己構造物件 15 print(ap.color)json反序列化物件
4.4 如何將大量資料寫進檔案?
不用 dump. 改用dumps和loads. 對每一行分別進行處理.
用dumps將資料逐個序列化, 並寫進檔案; 用loads逐行將字串反序列化, 並輸出(不能用load, 逐行讀出來的字串是不符合json語法規範, 沒法load, 會直接報錯).
1 # 用json寫進大量資料 2 dic1 = {"name":"亂世佳人","show_time":1975,"score":8.5,"time":"180min"} 3 dic2 = {"name":"聞香識女人","show_time":1998,"score":8.8,"time":"160min"} 4 dic3 = {"name":"飛越瘋人院","show_time":1973,"score":8.7,"time":"140min"} 5 dic4 = {"name":"霸王別姬","show_time":2001,"score":9.3,"time":"150min"} 6 lst = [dic1,dic2,dic3,dic4] 7 # with open("movie.json","w",encoding="utf8") as f: 8 # for i in lst: 9 # s = json.dumps(i,ensure_ascii=False) 10 # f.write(s+"\n") 11 12 with open("movie.json","r",encoding="utf8") as f: 13 for line in f: 14 line = line.strip() 15 if not line: 16 continue 17 cont = json.loads(line) # 只是一個反序列化操作, 把字串式的line轉成字典形式. 18 # cont = json.load(line) # 錯誤寫法, 這裡line只是讀取了json檔案的一行,並沒有全部讀取, 19 # line裡面所存的字串是不符合json語法的,沒法load, 所以讀取出錯. 20 print(cont)json寫入大量資料