什麼是序列化/反序列化?json
序列化就是將內存中的數據結構轉換成一種中間格式存儲到硬盤或者基於網絡傳輸,反序列化就是硬盤中或者網絡中傳來的一種數據格式轉換成內存中數據結構網絡
爲何要有序列化/反序列化?數據結構
一、能夠保存程序的運行狀態app
二、數據的跨平臺交互ide
shelve模塊:也用於序列化,它於 pickle 不一樣之處在於不須要關心文件模式等,而是直接把它當成一個字典來看待,它能夠直接對數據進行修改,而不用覆蓋原來的數據,但 pickle 想要修改只能用 wb 模式來覆蓋編碼
import shelve dic1 = {'pwd': 'qiu123', 'age': 22} dic2 = {'pwd': 'xi456', 'age': 22} d = shelve.open('db.txt') d['qiu'] = dic1 d['xi'] = dic2 print(d['qiu']['pwd']) d.close()
import shelve d = shelve.open('db.txt') print(d['qiu']) print(d['qiu']['pwd']) d.close()
import shelve # 對子字典的修改須要參數
d = shelve.open('db.txt', writeback=True) d['qiu']['age'] = 20
print(d['qiu']) d.close()
pickle模塊:一個用來序列化的模塊url
主要功能有dump(序列化)、load(反序列化)、dumps、loads。dump/load 相比於 dumps/loads,封裝了 write 和 read,使用操做更方便spa
import pickle dic = {'a':1, 'b':2, 'c':3} # 1. 序列化
pkl = pickle.dumps(dic) print(pkl, type(pkl)) # 2. 寫入文件
with open('db.pkl', 'wb') as f: f.write(pkl) # 1和2能夠合成一步
with open('db.pkl', 'wb') as f: res = pickle.dump(dic, f)
import pickle # 1. 從文件中讀取pickle格式
with open('db.pkl', 'rb') as f: pkl = f.read() # 2. 將pkl_str轉成內存中的數據類型
dic = pickle.loads(pkl) print(dic) # 1和2能夠合成一步
with open('db.pkl', 'rb') as f: dic = pickle.load(f) print(dic)
優勢:能夠支持 Python 中全部的數據類型翻譯
缺點:只能被 Python 識別,不能跨平臺3d
json模塊:一個用於序列化的模塊
在使用 json 模塊以前,須要先了解 JSON(JavaScript Object Notation,JS的對象簡譜),它表示出來的是一個字符串,能夠被任何語言解析讀取,方便使用
JSON 表示的對象就是標準的 JavaScript 語言的對象,JSON 和 Python 內置的數據類型對應以下:
import json dic = {'name': 'qiuxi', 'age': 22} # 序列化: 內存中的數據類型轉化成中間格式json
json_str = json.dumps(dic) print(json_str, type(json_str)) # 運行
{"name": "qiuxi", "age": 22} <class 'str'>
JSON格式不能識別單引號,全都是雙引號
import json dic = {'name': 'qiuxi', 'age': 22} # 1. 序列化獲得json_str
json_str = json.dumps(dic) # 2. 把json_str寫入文件 # 由於json表示出來的都是字符串, 因此用wt且指定編碼
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)
import json # 1. 從文件中讀取json格式
with open('db.json', 'rt', encoding='utf-8') as f: json_str = f.read() # 2. 將json_str轉成內存中的數據類型
dic = json.loads(json_str) print(dic) # 1和2合併一步
with open('db.json', 'rt', encoding='utf-8') as f: dic = json.load(f) print(dic)
當本身手寫的 json 文件時,能夠到網上進行JSON格式化校驗
優勢:跨平臺性強
缺點:只能支持 Python 部分的數據類型
xml模塊:也是用於序列化的一種模塊
在使用 xml 模塊以前,須要先了解 XML(可擴展標記語言),也是一種通用的數據格式。
語法格式:
一、任何的起始標籤都必須有一個結束標籤
二、能夠採用另外一種簡化語法,能夠在一個標籤中同時表示起始和結束標籤。這種語法是在大於符號以前緊跟一個斜線(/),例如<百度百科詞條/>,XML解析器會將其翻譯成 <百度百科詞條></百度百科詞條>
三、標籤必須按合適的順序進行嵌套,因此結束標籤必須按鏡像順序匹配起始籤。這比如是將起始和結束標籤看做是數學中的左右括號:在沒有關閉全部的內部括號以前,是不能關閉外面的括號的。
四、全部的屬性都必須有值
五、全部的屬性都必須在值的周圍加上雙引號
標籤的組成
<tagname attributename="value">text <subtags/>
</tagname>
<標籤名 屬性="屬性值">文本 </子標籤>
</標籤名>
import xml.etree.ElmentTree # 表示節點樹
<studentinfo>
<stu age="20" name="張三">
<phone name="華爲">這是華爲手機</phone>
<computer name="Mac">14888</computer>
</stu>
<stu age="22" name="李四">
<phone name="華爲">這是華爲手機</phone>
<computer name="聯想">4888</computer>
</stu>
</studentinfo>
標籤的三個特徵:標籤名tag、標籤屬性attrib、標籤的文本內容text
import xml.etree.ElementTree as ET # 解析d.xml
tree = ET.parse('d.xml') print(tree) # 獲取根標籤
rootTree = tree.getroot() # 第一種獲取標籤的方式 # iter用於在全文範圍獲取標籤
for item in rootTree.iter('phone'): print(item.tag) # 標籤名
print(item.attrib) # 標籤的屬性
print(item.text) # 文本內容
# 第二種獲取標籤的方式 # find用於從根標籤的子標籤中查找一個名爲stu的標籤, 若是有多個, 找到的是第一個
print(rootTree.find('stu').attrib) # 第三種獲取標籤的方式 # findall用於從同級標籤中查找全部名爲phone的標籤
print(rootTree.findall('phone')) # 一、查 # 遍歷整個文檔
for stu in rootTree: for item in stu: print(item.tag) print(item.attrib) print(item.text) # 二、改
for phone in rootTree.iter('phone'): print(phone.tag) phone.attrib = {'name': '華爲'} phone.text = '這是華爲手機' tree.write('d.xml',encoding='utf-8') # 三、增
for stu in rootTree: computer = stu.find('computer') if int(computer.text) > 5000: print('價錢大於5000的電腦的使用者', stu.attrib) tag = ET.Element('qiuxi') tag.attrib = {'hobby': 'music'} tag.text = '喜歡音樂' stu.append(tag) tree.write('d.xml', encoding='utf-8') # 四、刪
for stu in rootTree: tag = stu.find('qiuxi') if tag is not None: print("========") stu.remove(tag) tree.write('d.xml', encoding='utf-8')
configparser模塊:用於解析配置文件的模塊
配置文件即包含配置程序信息的文件,一些須要修改但不常常修改的信息,例如數據文件的路徑等
配置文件中只有兩種內容,一種是 section 分區,另外一種是 option 選項,就是一個 key=value 形式
使用最多的是 get ,用來從配置文件獲取一個配置選項
# 路徑的相關配置
[path] db_path = C://myfile/test.txt # 用戶相關的配置
[user] name = qiuxi age = 22
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(config.get('user', 'age')) # get返回的都是字符串類型, 若是須要轉換類型, 直接使用get+對應的類型
print(type(config.getint("user","age"))) # 是否有某個分區
print(config.has_section('user')) # 是否有某個選項
print(config.has_option('user', 'name')) # 一些不太經常使用的操做 # 添加
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)