python序列化和JSON
阿新 • • 發佈:2018-12-22
為什麼把這兩個放到一起,理由很簡單,不過暫時不解釋。
一,先看python提供的序列化模組pickle
import pickle l = ['柯基', '小李', '大華'] lw = pickle.dumps(l) # 把物件轉乘位元組流 也就是序列化 print(lw) with open('l.txt', 'wb') as f: #位元組流寫入檔案 f.write(lw) with open('l.txt', 'rb') as f: #從檔案中讀取位元組流 lr = f.read() newl = pickle.loads(lr) #把位元組流轉換成物件 print(newl) Output: b'\x80\x03]q\x00(X\x06\x00\x00\x00\xe6\x9f\xaf\xe5\x9f\xbaq\x01X\x06\x00\x00\x00\xe5\xb0\x8f\xe6\x9d\x8eq\x02X\x06\x00\x00\x00\xe5\xa4\xa7\xe5\x8d\x8eq\x03e.' ['柯基', '小李', '大華']
大段程式碼都是檔案操作,因為要儲存起來嘛,所以真正的序列化和反序列化非常簡單,dumps()和loads()就結束了。
緊接著看一個簡化版就好理解了:
import pickle
l = ['柯基', '小李', '大華']
with open('l.txt', 'wb') as f:
pickle.dump(l, f)
with open('l.txt', 'rb') as f: #從檔案中讀取位元組流
newl = pickle.load(f)
print(newl)
Output:
['柯基', '小李', '大華']
就是提供了兩個新的函式dump()和load()把寫入檔案從檔案讀這個過程也給封裝了。
二,JSON--JSON是UTF-8編碼,因為要在網路上傳輸嘛 節約
現在來回答這個問題,很明顯,用pickle序列化的東西,只能用pickle去反序列化,實際上你開啟儲存pickle序列化的檔案,裡面全是一些亂碼,所以上面的資料傳輸就現在了python系統內部。JSON就是用來解決這個問題的,JSON是JavaScript的物件表示法,但是因為各種優點,就成了網路上傳輸資料的一種標準格式。所以把物件序列化乘JSON格式,就可以和其他語言進行通訊。
python也內建了json模組:
import json l = ['柯基', '小李', '大華'] print(json.dumps(l)) #把python物件轉成json物件 newl = json.loads('["\u67ef\u57fa", "\u5c0f\u674e", "\u5927\u534e"]') #把json物件轉成python物件 print(newl) Output: ["\u67ef\u57fa", "\u5c0f\u674e", "\u5927\u534e"] ['柯基', '小李', '大華']
當然也有dump()和load() 這裡不演示了。可以看到python的list就直接被轉換成了json的陣列[],其餘的還有python的dict會被轉換成json的物件{}。
題外話:學到這裡,我才明白為什麼說python簡單,容易入門, 其一是因為內建了大量有用的模組,其二是它這個介面設計的,都一樣- -,用起來你就很舒服。
三,接下來看看怎麼用josn序列化類
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def Person2Dict(p):
return{
'name':p.name,
'age':p.age
}
p = Person('張三',33)
print(json.dumps(p, default=Person2Dict, ensure_ascii=False)) #ensure_ascii=False中文不按ascii編碼
Output:
{"name": "張三", "age": 33}
這裡dumps()方法多了一個default屬性,就是告訴json模組怎麼把我的類轉換成json物件,可以看到 Person2Dict實際上是把我們自定義的型別轉換成了可以序列化的基本型別。然後dumps實際是去序列化這個基本型別去了。
再看反序列化:
def Dict2Person(d):
return Person(d['name'], d['age'])
jsonStr = '{"name": "張三", "age": 33}'
#newP = json.loads(jsonStr)
#newP = Dict2Person(newP)
newP = json.loads(jsonStr, object_hook=Dict2Person)
print(newP.name, newP.age)
Output:
張三 33
可以想想loads()新增object_hook引數之後,就相當於上面註釋掉的兩句程式碼,先轉成dict,然後再用我們寫好的方法去例項化物件。