python學習的第21天模組之pickle、json、xml、shelve、configparser
一、pickle ***
1、作用;專門用於python語言的序列化
PS;(1)什麼是序列化?
指的是將記憶體中的資料結構轉化為一種中間格式,並存儲到硬碟上
(2)什麼是反序列化?
將硬碟上儲存的中間格式資料在還原為記憶體中的資料結構
(3)為什麼要序列化?
為了將資料持久儲存,之前學過的檔案也能完成持久化儲存,但是操作起來非常麻煩
Pickle模組主要功能:dump、load、dunmps、loads
dump是序列化,load是反序列化
注意:
dump和dumps、load和loads的區別:不帶s 是幫你封裝write和read更方便
load函式可以多次執行 每次load 都是往後在讀一個物件 如果沒有了就丟擲異常Ran out of input
先建立一個檔案,使用者註冊後得到的資料
name = "高跟" password = "123" height = 1.5 hobby = ["吃","喝","賭","飄",{1,2,3}] # with open("userdb.txt","wt",encoding="utf-8") as f: # text = "|".join([name,password,str(height)]) # f.write(text)
pickle支援python中所有的資料型別 user = {"name":name,"password":password,"height":height,"hobby":hobby,"test":3}
序列化的過程 # with open("userdb.pkl","ab") as f: # userbytes = pickle.dumps(user) # f.write(userbytes)
# 反序列化過程 # with open("userdb.pkl","rb") as f: # userbytes = f.read() # user = pickle.loads(userbytes) # print(user) # print(type(user))
#dump 直接序列化到檔案 # with open("userdb.pkl","ab") as f: # pickle.dump(user,f) # #load 從檔案反序列化 with open("userdb.pkl","rb") as f: user = pickle.load(f) print(user) print(pickle.load(f))
#dump 直接序列化到檔案 # with open("userdb.pkl","ab") as f: # pickle.dump(user,f) # #load 從檔案反序列化 with open("userdb.pkl","rb") as f: user = pickle.load(f) print(user) print(pickle.load(f))
二、shelve
1、作用:極其簡單的序列化模組,只用於python
優點:shelve模組 也用於序列化,它於pickle不同之處在於 不需要關心檔案模式什麼的 直接把它當成一個字典來看待,
它可以直接對資料進行修改 而不用覆蓋原來的資料,而pickle 你想要修改只能 用wb模式來覆蓋
shelve模組比pickle模組簡單,只有一個open函式,返回類似字典的物件,可讀可寫;key必須為字串,而值可以是python所支援的資料型別
import shelve
# user = {"name":"高根"}
# s = shelve.open("userdb.shv")
# s["user"] = user
# s.close()
s = shelve.open("userdb.shv",writeback=True)
print(s["user"])
s["user"]["age"] = 20
s.close()
三、json *****
1、作用是一種跨平臺的資料格式 也屬於序列化的一種方式
2、為什麼用:
pickle 和 shevle 序列化後得到的資料 只有python才能解析
通常企業開發不可能做一個單機程式 都需要聯網進行計算機間的互動
我們必須保證這個資料 能夠跨平臺使用
js 中的資料型別 python資料型別 的對應關係 {} 字典 [] list string "" str int/float int/float true/false True/False null None
3、怎麼用:
json格式的語法規範
最外層通常是一個字典或列表{} or []
只要你想寫一個json格式的資料 那麼最外層直接寫{},且字串必須是雙引號
你可以在裡面套任意多的層次
對於我們開發而言 json就是一種通用的資料格式 任何語言都能解析
json儲存資料取必須都是python資料結構 js 中的資料型別 python資料型別 的對應關係 {} 字典 [] list string "" str int/float int/float true/false True/False null None
json模組的核心功能
dump、dumps、load、loads 不帶s 封裝write 和 read
(1)json的序列化
import json dic={'name':'egon','age':18,'sex':'male'} #序列化:記憶體中的資料型別------>中間格式json # # 1、序列化得到json_str # json_str=json.dumps(dic) # # 2、把json_str寫入檔案 # with open('db.json','wt',encoding='utf-8') as f: # f.write(json_str) #1和2合為一步 with open('db.json','wt',encoding='utf-8') as f: json.dump(dic,f) # print(json_str,type(json_str)) # json格式不能識別單引號,全都是雙引號
(2)json的反序列化
import json #反序列化:中間格式json-----》記憶體中的資料型別 # #1、從檔案中讀取json_str # with open('db.json','rt',encoding='utf-8') as f: # json_str=f.read() # #2、將json_str轉成記憶體中的資料型別 # dic=json.loads(json_str) #1和2可以合作一步 with open('db.json','rt',encoding='utf-8') as f: dic=json.load(f) print(dic['sex'])
四、xml
1、作用:可擴充套件標記語言,一種編寫文件的語法 也支援跨平臺,比較json而言 屬於重量級(不實用)
import xml.etree.ElementTree as ET tree = ET.parse("a.xml") root = tree.getroot()
學習的重點還是語法格式
(一)、任何的起始標籤都必須有⼀一個結束標籤。
<> </>
(二)、可以採用另一種簡化語法,可以在一個標籤中同時表示起始和結束標
籤。這種語法是在⼤於符號之前緊跟一個斜線(/),XML
解析器會將其翻譯成<百度百科詞條></百度百科詞條>。
例例如<百度百科詞條/>。
(三)、標籤必須按合適的順序進⾏行行巢狀,所以結束標籤必須按映象順序匹配
起始標籤。這好⽐比是將起始和結束標籤看作是數學中的左右括號:在沒有關閉所有
的內部括號之前,是不不能關閉外⾯面的括號的。
(四)、所有的特性都必須有值。
(五)、所有的特性都必須在值的周圍加上雙引號。
一個標籤的組成部分 <tagename 屬性名稱="屬性值">文字內容 </tagname> 單標籤的寫法 <tagename 屬性名稱="屬性值"/> # 映象關閉順序例項 <a> <b> <c> </c> </b> </a>
把你左右同學的資訊寫成xml <studentinfo> <張三> <age>20</age> <gender>man</gender> </張三> <李四> <age>20</age> <gender>man</gender> </李四> </studentinfo> 總結 xml也是一種中間格式 也屬於序列化方式之一 與json相比較 同樣的資料 json會比xml 更小 效率更高 xml 需要根據文件結構 手動解析 而json 直接轉物件
import xml.etree.ElementTree as ElementTree # 解析d.xml tree = ElementTree.parse("d.xml") print(tree) # 獲取根標籤 rootTree = tree.getroot() # 三種獲取標籤的方式 # 獲取所有人的年齡 iter是用於在全文範圍獲取標籤 # for item in rootTree.iter("age"): # # 一個標籤三個組成部分 # print(item.tag) # 標籤名稱 # print(item.attrib) # 標籤的屬性 # print(item.text) # 文字內容 # 第二種 從當前標籤的子標籤中找到一個名稱為age的標籤 如果有多個 找到的是第一個 # print(rootTree.find("age").attrib) # 第三種 從當前標籤的子標籤中找到所有名稱為age的標籤 # print(rootTree.findall("age"))
# 獲取單個屬性 stu = rootTree.find("stu") print(stu.get("age")) print(stu.get("name")) # 刪除子標籤 rootTree.remove(stu) # 新增子標籤 # 要先建立一個子標籤 newTag = ElementTree.Element("這是新標籤",{"一個屬性":"值"}) rootTree.append(newTag) # 寫入檔案 tree.write("f.xml",encoding="utf-8")
五、configparser *****
1、作用:用於解析配置檔案的模組
何為配置檔案:包含配置程式資訊的檔案就稱為配置檔案
什麼樣的資料應作為配置資訊:需要改 但是不經常改的資訊 例如資料檔案的路徑 DB_PATH
2、用法:
配置檔案中 只有兩種內容
一種是section 分割槽
一種是option 選項 就是一個key=value形式
我們用的最多的就是get功能 用來從配置檔案獲取一個配置選項
import configparser # 建立一個解析器 config = configparser.ConfigParser() # 讀取並解析test.cfg config.read("test.cfg",encoding="utf-8") # 獲取需要的資訊 # 獲取所有分割槽 # print(config.sections()) # 獲取所有選項 # print(config.options("user")) # 獲取某個選項的值 # print(config.get("path","DB_PATH")) # print(type(config.get("user","age"))) # # # get返回的都是字串型別 如果需要轉換型別 直接使用get+對應的型別(bool int float) # print(type(config.getint("user","age"))) # print(type(config.get("user","age")))
是否由某個選項 config.has_option() # 是否由某個分割槽 # config.has_section() # 不太常用的 # 新增 # config.add_section("server") # config.set("server","url","192.168.1.2") # 刪除 # config.remove_option("user","age") # 修改 # config.set("server","url","192.168.1.2") # 寫回檔案中 # with open("test.cfg", "wt", encoding="utf-8") as f: # config.write(f)