1. 程式人生 > >Python課程回顧(day19)

Python課程回顧(day19)

常用模組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()                   # 轉換成布林型別