python中常用的序列化模块_第六章 常用模块(5):python常用模块(序列化模块:pickle,json,shelve,xml)...
6.3.7 序列化模塊 (pickle,json,shelve,xml)
文件寫入,數(shù)據(jù)傳輸時,我們都是以字符串形式寫入的(因為字符串可以encode成bytes)。
那其他類型(比如字典,列表等)想寫入文件時如何處理呢?
這時候我們就需要一種操作,叫做序列化。
+那什么是序列化呢?
+ 把內(nèi)存數(shù)據(jù)(unicode)轉(zhuǎn)成字符(bytes類型),叫做序列化。
>序列化用于存入硬盤或者網(wǎng)絡(luò)傳輸?shù)?/p>
+ 把字符轉(zhuǎn)成內(nèi)存數(shù)據(jù),叫反序列化。
簡單點說,就是:
序列化: 其他類型數(shù)據(jù) --> 字符類型
反序列化: 字符類型 --> 其他數(shù)據(jù)類型
>字符類型:str, bytes or bytearray
可以序列化,反序列化的模塊有以下2種:
pickle
json
這兩種模塊的用法完全一樣
用eval()方法也可以達到效果。那有什么區(qū)別呢?
1. json模塊 (.json文件)
序列化成字符串類型
json特點
需要用open打開文件再處理
用'w','r'等類型打開文件進行
序列化成字符串類型
文件擴展名用.json
json與pickle的區(qū)別:
json能識別的數(shù)據(jù)類型:str,int,tuple,list,dict
json可以跨平臺使用
import json
json.dump(obj,fp,skipkeys,...)
將obj序列化成字符串類型,并寫入文件對象fp中。返回None
json.dumps():將數(shù)據(jù)轉(zhuǎn)成字符串并存到內(nèi)存
這個一般用在:1.網(wǎng)絡(luò)數(shù)據(jù)傳輸 2.跨平臺,跨語言的數(shù)據(jù)交互
json.load(fp,cls,...)
讀取json序列化的文件對象fp,反序列,返回反序列后的數(shù)據(jù)
json.loads():讀取dumps的數(shù)據(jù),并反序列
import json
data = {'name': 'Alex', 'age': 22, 'salary': [1, 2, 3]}
# d1 = json.dumps(data) # 把data序列化。 ->序列化后轉(zhuǎn)為str類型
# d2 = json.loads(data) # 把data反序列化。 ->反序列化轉(zhuǎn)成相應(yīng)數(shù)據(jù)類型(字典,列表等)
with open('test.json','w') as f: # 一般json序列化的文件擴展名用.json
d1 = json.dump(data,f) # 把data序列化,并且寫入文件對象f中。因為返回None,所以d1是None
with open('test.json','r') as f:
d2 = json.load(f) # 把文件對象f的數(shù)據(jù)反序列化,返回給d2
拓展:數(shù)據(jù)交互方式有2種:json,xml
json 可讀性,數(shù)據(jù)大小 都優(yōu)越于 xml
Azure的舊環(huán)境用的xml,新環(huán)境用的json
2. pickle模塊 (.pkl文件)
序列化成bytes類型。
注意:因為序列化成bytes類型,所以文件的讀寫要用rb,wb等模式來進行!
pickle特點
需要用open打開文件再處理
用'wb','rb'等類型打開文件進行
序列化成bytes類型
文件擴展名用.pkl
pickle與json的區(qū)別:
pickle支持python里所有的數(shù)據(jù)類型(比如函數(shù),類什么的都可以)
所以python使用的文件,不論內(nèi)容時什么我們都可以pickle
pickle只能在python里使用
import pickle
pickle.dump(obj,file,protocol,...)
將obj序列化成bytes類型,并寫入file文件,如果沒有會創(chuàng)建文件。返回None
pickle.load(file,...)
讀取json序列化的文件對象fp,反序列,返回反序列后的數(shù)據(jù)
.loads():讀取dumps的數(shù)據(jù),并反序列
import pickle
data = [1, 2, 3]
d1 = pickle.dumps(data) # 把data序列化。 ->序列化后轉(zhuǎn)為bytes類型
d2 = pickle.loads(d1) # 把data反序列化。 ->反序列化轉(zhuǎn)成相應(yīng)數(shù)據(jù)類型
with open('test.pkl', 'wb') as f: # 一般pickle序列化的文件擴展名用.pkl
pickle.dump(data, f)
with open('test.json', 'rb') as f:
d = pickle.load(f)
print(type(d1))
print(type(d2))
print(d)
3. shelve模塊 ()
shelve對pickle進行了封裝,并且可以多次dump和load
區(qū)別及特點:
pickle
一個文件只能dump一次(因為dump多次容易混亂)
用open()函數(shù)打開文件
shelve
可以對文件多次dump,load
用shelve模塊的.open()方法打開文件
數(shù)據(jù)的結(jié)構(gòu)類似dict
可以直接用類似處理dict的方法處理數(shù)據(jù)
序列化:
import shelve
f = shelve.open('shelve_test') # 打開(沒有就創(chuàng)建)文件。會創(chuàng)建多個文件??梢愿鷒pen一樣用with
list1 = ['a','b','c','d']
dict1 = {'key1':'abcd','key2':'1234'}
f['li1'] = list1 # 持久化列表 --> 就是寫入序列化文件中,并且有個名字是'li1'
f['d1'] = dict1 # 持久化字典 --> 就是寫入序列化文件中,并且有個名字是'd1'
f.close() # 關(guān)閉保存
反序列化:
import shelve
with shelve.open('shelve_test') as f:
print(f['li1']) # 直接調(diào)用li1的數(shù)據(jù)
print(f['d1']) # 直接調(diào)用d1的數(shù)據(jù)
# shelve打開的文件對象構(gòu)造類似字典,可以使用字典的方法:
print('get li1:', f.get('li1')) # 有g(shù)et()方法
i = f.items() # 有items()方法。 注意:這個i指向f.items()的內(nèi)存地址,f.items()的值變化,i也會隨之變化
print(id(i))
print(i) # 返回值是shelve對象類型,不能直接使用
print(list(i)) # 所以需要list()轉(zhuǎn)換一下才可以看到內(nèi)容
f['li2'] = ['aaaa','bbbb'] # 可以追加新的數(shù)據(jù)
print(list(i))
f.pop('li2') # 可以刪除
print(list(i))
f['li1'] = [2, 3, 4, 5] # 可以直接修改某個數(shù)據(jù)的整個內(nèi)容
print(list(i))
f['li1'][1] = 'b' # 但是不能改其中的一部分內(nèi)容(字典可以)
print(list(i)) # 結(jié)果并沒有改變
print(id(i))
4. xml模塊 (.xml)
作用和json一樣,是json出現(xiàn)之前很常用的序列化模塊。
構(gòu)造也和字典類似。用<>來定義數(shù)據(jù)。
讀取xml文檔內(nèi)容:
# 讀取數(shù)據(jù)
import xml.etree.ElementTree as ET
tree = ET.parse('test.xml') # 打開xml文件,返回xml對象
root = tree.getroot() # 取數(shù)據(jù)最上級key
# print(dir(root)) # 可以顯示數(shù)據(jù)的keys
print(root.tag)
# 遍歷文檔
for child in root:
print(child.tag, child.attrib)
for i in child:
print(i.tag, i.attrib)
# 只遍歷year節(jié)點
for node in root.iter('year'):
print(node.tag, node.text)
修改和刪除xml文檔內(nèi)容:
# 修改數(shù)據(jù)
import xml.etree.ElementTree as ET
tree = ET.parse('test.xml')
root = tree.getroot() # 取數(shù)據(jù)最上級key
# 修改
for node in root.iter('year'):
new_year = int(node.text) + 1 # 取數(shù)據(jù)并計算
node.text = str(new_year) # 把值轉(zhuǎn)成str并賦值給原來的內(nèi)容
node.set('update', 'yes') # 設(shè)置屬性和值
tree.write('test.xml') # 內(nèi)容寫入文件
# 刪除數(shù)據(jù)
import xml.etree.ElementTree as ET
tree = ET.parse('test.xml')
root = tree.getroot() # 取數(shù)據(jù)最上級key
# 刪除node
for country in root.findall('country'):
rank = int(country.find('rank').text)
if rank > 50:
root.remove(country)
tree.write('output.xml') # 結(jié)果寫到一個新文件里
創(chuàng)建xml文件
```python
# 創(chuàng)建xml文件
import xml.etree.ElementTree as ET
root = ET.Element('namelist') # 創(chuàng)建名為namelist的根(root)
name1 = ET.SubElement(root,'name',attrib={'enrolled':'yes'}) # 名稱為'name'的數(shù)據(jù)放在'root'的節(jié)點上,屬性設(shè)為{'enrolled':'yes'}
age = ET.SubElement(name1,'age',attrib={'checked':'no'}) # 名稱為'age'的數(shù)據(jù)放在name1的節(jié)點上,屬性設(shè)置為 {'checked':'no'}
sex = ET.SubElement(name1,'sex') # 名稱為'sex'的數(shù)據(jù)放在name1的節(jié)點上
sex.text = '33' # sex的值設(shè)為'33'
name2 = ET.SubElement(root,'name',attrib={'enrolled':'no'}) # 名稱為'name'的數(shù)據(jù)放在'root'的節(jié)點上,屬性設(shè)為{'enrolled':'yes'}
age = ET.SubElement(name2,'age') # 名稱為'age'的數(shù)據(jù)放在name2的節(jié)點上
age.text = '19' # age的值設(shè)為'19'
et = ET.ElementTree(root) # 生成文檔對象
et.write('test.xml', encoding='utf-8', xml_declaration=True) # xml_declaration是要不要加版本號聲明
ET.dump(root)
```
總結(jié)
以上是生活随笔為你收集整理的python中常用的序列化模块_第六章 常用模块(5):python常用模块(序列化模块:pickle,json,shelve,xml)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 企业付款到零钱 java_微信支付商户如
- 下一篇: matlab 子图title的位置_Pl