將本來的字典、列表等內容轉換成一個字符串的過程就叫作序列化。java
序列:列表、元祖、字符串、bytespython 序列化:字符串、bytesjson |
可以在網絡上傳輸的只能是bytes,安全
可以存儲在文件裏的只有bytes和str網絡
序列化的目的數據結構 一、以某種存儲形式使自定義對象持久化;函數 二、將對象從一個地方傳遞到另外一個地方。學習 三、使程序更具維護性。spa
|
好比,咱們在python代碼中計算的一個數據須要給另一段程序使用,那咱們怎麼給?code 如今咱們能想到的方法就是存在文件裏,而後另外一個python程序再從文件裏讀出來。 可是咱們都知道,對於文件來講是沒有字典這個概念的,因此咱們只能將數據轉換成字典放到文件中。 你必定會問,將字典轉換成一個字符串很簡單,就是str(dic)就能夠辦到了,爲何咱們還要學習序列化模塊呢? 沒錯序列化的過程就是從dic 變成str(dic)的過程。如今你能夠經過str(dic),將一個名爲dic的字典轉換成一個字符串, 可是你要怎麼把一個字符串轉換成字典呢? 聰明的你確定想到了eval(),若是咱們將一個字符串類型的字典str_dic傳給eval,就會獲得一個返回的字典類型了。 eval()函數十分強大,可是eval是作什麼的?e官方demo解釋爲:將字符串str當成有效的表達式來求值並返回計算結果。 BUT!強大的函數有代價。安全性是其最大的缺點。 想象一下,若是咱們從文件中讀出的不是一個數據結構,而是一句"刪除文件"相似的破壞性語句,那麼後果實在不堪設設想。 而使用eval就要擔這個風險。 因此,咱們並不推薦用eval方法來進行反序列化操做(將str轉換成python中的數據結構) s="{1:2}"
|
Json模塊提供了四個功能:dumps、dump、loads、load
# json # dumps loads # 在內存中作數據轉換 : # dumps 數據類型 轉成 字符串 序列化 (在內存中操做) # loads 字符串 轉成 數據類型 反序列化 # dump load # 直接將數據類型寫入文件,直接從文件中讀出數據類型 # dump 數據類型 寫入 文件 序列化 # load 文件 讀出 數據類型 反序列化 # json是全部語言都通用的一種序列化格式 # 只支持 列表 字典 字符串 數字 # 字典的key必須是字符串 |
dic = {'key' : 'value','key2' : 'value2'} ret = json.dumps(dic) #序列化 print(dic,type(dic)) #{'key': 'value', 'key2': 'value2'} <class 'dict'> print(ret,type(ret)) #{"key": "value", "key2": "value2"} <class 'str'> res = json.loads(ret) #反序列化 print(res,type(res)) #{'key': 'value', 'key2': 'value2'} <class 'dict'>
能夠看到序列化和反序列化後key值的類型-----》字符串類型,
因此對於字典的約束:key是字符串類型
dic = {1:'value',2:'value2'} ret = json.dumps(dic) #序列化 print(dic,type(dic)) #{1: 'value', 2: 'value2'} <class 'dict'> print(ret,type(ret)) #{"1": "value", "2": "value2"} <class 'str'> res = json.loads(ret) #反序列化 print(res,type(res)) #{'1': 'value', '2': 'value2'} <class 'dict'>
|
dic = {1 : [1,2,3],2 : (4,5,'aa')} ret = json.dumps(dic) # 序列化 print(dic,type(dic)) #{1: [1, 2, 3], 2: (4, 5, 'aa')} <class 'dict'> print(ret,type(ret)) #{"1": [1, 2, 3], "2": [4, 5, "aa"]} <class 'str'> res = json.loads(ret) # 反序列化 print(res,type(res)) #{'1': [1, 2, 3], '2': [4, 5, 'aa']} <class 'dict'>
|
s = {1,2,'aaa'} json.dumps(s) #TypeError
json.dumps({(1,2,3):123}) #TypeError: keys must be a string
dic = {'key1' : 'value1','key2' : 'value2'} with open('json_file','a') as f: json.dump(dic,f) json.dump(dic,f) json.dump(dic,f) with open('json_file','r') as f: dic = json.load(f) print(dic.keys())
#向文件中記錄字典 dic = {'key' : 'value','key2' : 'value2'} ret = json.dumps(dic) with open('json_file','a') as f: f.write(ret) #從文件中讀取字典 with open('json_file','r') as f: str_dic = f.read() di = json.loads(str_dic) print(di)
注意: json只能識別一個字典,若是多個字典在一行,當反序列化的時候就會報錯,因此能夠把字典放不一樣的行,並在讀文件時,readline一行一行讀
# 需求 :就是想要把一個一個的字典放到文件中,再一個一個取出來??? dic = {'key1' : 'value1','key2' : 'value2'} with open('json_file','a') as f: str_dic = json.dumps(dic) f.write(str_dic+'\n') str_dic = json.dumps(dic) f.write(str_dic + '\n') str_dic = json.dumps(dic) f.write(str_dic + '\n') with open('json_file','r') as f: for line in f: dic = json.loads(line.strip()) print(dic.keys()) |
# json 在全部的語言之間都通用 : json序列化的數據 在python上序列化了 那在java中也能夠反序列化 # 可以處理的數據類型是很是有限的 : 字符串 列表 字典 數字 # 字典中的key只能是字符串 |
dic = {'key1' : 'value1','key2' : 'value2'} with open('json_file','a') as f: json.dump(dic,f) with open('json_file','r') as f: dic = json.load(f) print(dic)
結論:Dump和load直接操做文件 |
data = {'username':['李華','二愣子'],'sex':'male','age':16} json_dic2 = json.dumps(data,sort_keys=True,indent=4,separators=(',',':'),ensure_ascii=False) print(json_dic2)
結果:
{
"age":16,
"sex":"male",
"username":[
"李華",
"二愣子"
]
}
Skipkeys:默認值是False,若是dict的keys內的數據不是python的基本類型(str,unicode,int,long,float,bool,None),設置爲False時,就會報TypeError的錯誤。此時設置成True,則會跳過這類key ensure_ascii:,當它爲True的時候,全部非ASCII碼字符顯示爲\uXXXX序列,只需在dump時將ensure_ascii設置爲False便可,此時存入json的中文便可正常顯示。) indent:應該是一個非負的整型,若是是0就是頂格分行顯示,若是爲空就是一行最緊湊顯示,不然會換行且按照indent的數值顯示前面的空白分行顯示,這樣打印出來的json數據也叫pretty-printed json separators:分隔符,其實是(item_separator, dict_separator)的一個元組,默認的就是(‘,’,’:’);這表示dictionary內keys之間用「,」隔開,而KEY和value之間用「:」隔開。 sort_keys:將數據根據keys的值進行排序。
3 pickle模塊
用於序列化的兩個模塊 json,用於字符串 和 python數據類型間進行轉換 pickle,用於python特有的類型 和 python的數據類型間進行轉換 |
支持在python中幾乎全部的數據類型
pickle模塊提供了四個功能:dumps、dump(序列化,存)、loads(反序列化,讀)、load (不只能夠序列化字典,列表...能夠把python中任意的數據類型序列化)
(1)支持在python中幾乎全部的數據類型
(2)dumps 序列化的結果只能是字節
(3)只能在python中使用
(4)在和文件操做的時候,須要用rb wb的模式打開文件
(5)能夠屢次dump 和 屢次load
import pickle dic = {(1,2,3):{'a','b'},1:'abc'} ret = pickle.dumps(dic) print(ret) #結果:b'\x80\x03}q\x00(K\x01K\........ #結論:dumps 序列化的結果只能是字節 print(pickle.loads(ret)) #{(1, 2, 3): {'b', 'a'}, 1: 'abc'}
import pickle dic = {(1,2,3):{'a','b'},1:'abc'} with open('pickle_file','wb') as f: pickle.dump(dic,f) with open('pickle_file','rb') as f: ret = pickle.load(f) print(ret,type(ret)) #{(1, 2, 3): {'b', 'a'}, 1: 'abc'} <class 'dict'>
dic = {(1,2,3):{'a','b'},1:'abc'} dic1 = {(1,2,3):{'a','b'},2:'abc'} dic2 = {(1,2,3):{'a','b'},3:'abc'} dic3 = {(1,2,3):{'a','b'},4:'abc'} with open('pickle_file','wb') as f: pickle.dump(dic, f) pickle.dump(dic1, f) pickle.dump(dic2, f) pickle.dump(dic3, f) with open('pickle_file','rb') as f: ret = pickle.load(f) print(ret,type(ret)) ret = pickle.load(f) print(ret,type(ret)) ret = pickle.load(f) print(ret, type(ret)) ret = pickle.load(f) print(ret, type(ret))
with open('pickle_file','rb') as f: while True: try: ret = pickle.load(f) print(ret,type(ret)) except EOFError: break