Python課程回顧(day19)
阿新 • • 發佈:2018-11-11
常用模組2
1.json序列化與反序列化
在學習今天的內容之前我們首先要了解:
01.什麼是序列化
序列化其實可以用一句話概括,就是我們把記憶體中的資料儲存或傳輸的過程就稱之為序列化,在python中這種過程叫做picking。
02.為什麼要用序列化
首先我們要知道,一個程式或軟體的執行就是在處理一系列的狀態,而隨著這個狀態的不斷變化,它會以各種各樣的結構或形式儲存到記憶體中,而記憶體是無法永久儲存的,如果恰巧在這個時候電腦故障或者斷電,那麼我們之前所做的一切都將會被清空。而如果我們在斷電或故障之前將我們的資料永久的儲存到硬碟內,那麼我們下次再啟動程式的時候,程式就會基於上次的執行而執行,這個就稱之為序列化。而在序列化之後,不僅可以將資料永久的儲存到硬碟,還可以通過網路傳輸到別的機器上,如果收發的雙方約定好使用同一種序列化格式,那麼便打破了平臺語言的限制,就實現了跨平臺的各種互動。
03.json序列化與反序列化的具體應用
import json # # 1.序列化之json.dumps() # 會將括號內的任何型別轉成json所能識別的字串,json格式全部都是雙引號 # # data = {'name': 'klf', 'age': 18} # res = json.dumps(data) # with open('a.json', mode='wt', encoding='utf-8') as f: # f.write(res) # 儲存時json會將data內的所有單引號變為雙引號(各平臺通用格式) # # 2.反序列化之json.loads # x = "[1, true, null, false]" # res = json.loads(x) # 將true,false其他平臺上的關鍵字反序列化為python可以識別的關鍵字 # print(res) # 3.序列化之json.dump # data = {'name': 'klf', 'age': 18} # with open('a1.json', 'wt', encoding='utf-8') as f: # json.dump(data, f) # 使用dump可以更簡潔的將資料以json格式寫入檔案 # dump括號內的引數一個是資料,一個是檔名(會自動呼叫f.write) # 4.反序列化之json.load # with open('a1.json', 'rt', encoding='utf-8') as f1: # print(json.load(f1)) # 使用load可以更簡潔的將資料以反序列化格式讀取檔案 # json.load括號內的引數本質就是呼叫了f1.read的功能
總結:就目前來說,我們使用json可以更快更簡潔的將資料以各個平臺通用的格式進行寫入與讀取,但json也不是萬能的
它能識別python內的資料型別是有限的,遇到python內部獨有的資料型別它就不能識別了
可以識別的資料型別:(dict,list,str,None,True,False,int,float)
不可識別的資料型別:(set,tuple,或python獨有的等等)
2.pickle序列化與反序列化
import pickle # 1.序列化之pickle.dumps # s = {1, 2, 3, 4} # with open('a.pkl', 'wb') as f: # pickle是以bytes型別進行序列與反序列化的,所以以b模式寫入 # res = pickle.dumps(s) # 反序列化結果賦值給res # print(res, type(res)) # f.write(res) # 2.反序列化之pickle.loads # with open('a.pkl', 'rb') as f: # 再次強調pickle是以位元組型別進行的序列與反序列化,模式一定要b # data = f.read() # res = pickle.loads(data) # 反序列化結果賦值給res # print(res) # 3.序列化之pickle.dump # s = {1, 2, 3} # with open('a1.pkl', 'wb') as f: # b模式 # pickle.dump(s, f) # 過程等同於json.dump # with open('a1.pkl', 'rb') as f: # b模式 # res = pickle.load(f) # 過程等同於json.load # print(res)
總結:特點:pickle與json的根本區別就在於pickle是可以識別python內所有資料型別的,不過它會將這些資料型別以“Bytes”型別進行序列化與反序列
缺點:pickle也只能識別python內的資料型別,其他平臺的資料型別是識別不了的,所以相比較起json識別不了的資料型別它是有優勢的,
但set與tuple也是不常用的資料型別,所以整體來說pickle不常用。
3.shevle模組
import shelve # # info1 = {'age': 18, 'height': 180, 'weight': 80} # info2 = {'age': 73, 'height': 150, 'weight': 125} # # d = shelve.open('db.shv') # d['egon'] = info1 # d['alex'] = info2 # 寫入完成後會出現三個不同的檔案,不必管它,在不同的平臺會產生相應的且不同的檔案 # d.close() # 注意關閉檔案!!!!! # f = shelve.open('db.shv') # print(f['egon']) # print(f['alex']) # 直接根據之前儲存的變數名來讀取即可 # f.close() # 注意關閉檔案!!!!! # f = shelve.open('db.shv', writeback=True) # writeback的預設值為False,不修改為True則不能修改檔案內容 # f['egon']['age'] = 123 # 可以通過key來修改值 # f['alex']['height'] = 150 # 可以通過key來修改值 # f.close() # 注意關閉檔案!!!!!
4.xml模組
import xml.etree.ElementTree as ET tree = ET.parse('a.xml') # 解析檔案賦值給一個物件(拿到整棵樹) root = tree.getroot() # 拿到樹根 # 查詢的三種方式一之iter: # res = root.iter('name') # 會在整個樹形結構進行查詢,而且查詢到所有對應值 # print(res) # 得到一個迭代器物件 # for item in res: # print('='*50) # xml中查詢每一個元素都對應有三個特徵 # print(item.tag) # tag = 標籤名(即映象對應的兩個名稱,帶/的標籤起閉合作用) # print(item.attrib) # attrib = 屬性(放在標籤後的描述,可以不寫) # print(item.text) # text = 文字(即標籤的值) # 查詢的三種方式一之find: # res = root.find('ahead') # 只能在當前元素的下一級開始查詢,並且只找到一個就結束 # res1 = res.find('name') # 可以拿到當前層級再次進行具體查詢,但只能找當前層級下的分支,也是隻找到一個就結束查詢 # print(res1.text) # 查詢的三種方式一之findall: # res = root.findall('') # 只能在當前元素的下一級開始查詢,找到全部後結束 # for item in res: # print(item.tag) # print(item.attrib) # print(item.text)
# 使用for迴圈修改xml檔案裡的值
tree = ET.parse('b.xml')
root = tree.getroot()
for year in root.iter('year'):
year.text = str(int(year.text) + 1) # 由於檔案裡讀取的資料是字串型別所以要轉換成int型別相加
year.attrib = {'x':'y'} # 新增屬性要按照字典形式新增,且必須都是字串
# 但是寫回檔案要以str型別所以還要轉換
tree.write('c.xml')
# 在year大於2020年的主標籤內新增新的標籤
import xml.etree.ElementTree as ET
tree = ET.parse('b.xml')
root = tree.getroot()
for country in root.iter('year'):# 使用for迴圈增加與刪除
year = country.find('year') # 找到每個country下的year
if int(year.txt) > 2020: # 判斷
ele = ET.Element('egon') # 增加新的標籤(關鍵字Element)
ele.attrib = {'name': 'alex'} # 為標籤增添新的屬性
ele.text = 'beautiful' # 增加文字內容
country.append(ele) # 使用append將新標籤新增到當前標籤內
country.remove('year') # 使用remove刪除某個標籤
tree.write('b.xml') # 寫回原始檔
5.configparser模組
import configparser # 解析配置檔案 config = configparser.ConfigParser() config.read('my.ini') secs = config.sections() # 將所有標題全部取出 print(secs) print(config.options('klf')) # 將檔案內標題的option全部取出 res = config.get('klf', 'age') # get括號內需要傳入標題與標題下的option就可以將option的值取出 res1 = config.getint('klf', 'age') # getint會將取出的值轉換成int型別 config.getfloat() # 轉換成浮點型 config.getboolean() # 轉換成布林型別