1. 程式人生 > >Python之序列化模塊

Python之序列化模塊

pytho 反序列化 同一時間 this 方法 字典 並不是 設置 字典類

序列化模塊

  導入:import module

  序列化:數據類型和str之間的轉換,數據持久化(存儲),網絡交互(傳輸)本質:將程序中的數據類型轉成str

  反序列化:將字符串轉換為其本來的數據類型

  序列化和反序列化這些操作都是一次性的,一次轉換,一次還原  

(1) json (存文件,網絡傳輸)

json模塊只給我們提供了四個功能:

  序列化:dump,dumps   
  反序列化:load, loads

    dumps和loads:對數據類型進行序列化和反序列化

 1 import json
 2 
 3 dic = {k1: v1, k2: v2, 
k3: v3} 4 5 # 序列化:將一個字典轉換成一個字符串 6 str_dic = json.dumps(dic) 7 8 print(type(str_dic), str_dic) 9 # 結果: 10 # 註意,json轉換完的字符串類型的字典中的字符串是由""表示的 11 # <class ‘str‘> {"k3": "v3", "k1": "v1", "k2": "v2"} 12 13 14 # 反序列化:將一個字符串格式的字典轉換成一個字典 15 # 註意,要用json的loads功能處理的字符串類型的字典中的字符串必須由""表示 16
dic2 = json.loads(str_dic) 17 18 print(type(dic2), dic2) 19 # 結果: 20 # <class ‘dict‘> {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, ‘k3‘: ‘v3‘} 21 22 list_dic = [1, [a, b, c], 3, {k1: v1, k2: v2}] 23 str_dic = json.dumps(list_dic) # ps:也可以處理嵌套的數據類型 24 print(type(str_dic), str_dic) 25 # 結果: 26
# <class ‘str‘> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}] 27 28 list_dic2 = json.loads(str_dic) 29 print(type(list_dic2), list_dic2) 30 # 結果: 31 # <class ‘list‘> [1, [‘a‘, ‘b‘, ‘c‘], 3, {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘}]

    

    dump和load:對文件句柄進行序列化和反序列化

 1 import json
 2 
 3 f = open(json_file, w)
 4 dic = {k1: v1, k2: v2, k3: v3}
 5 
 6 # dump方法接收一個文件句柄,直接將字典轉換成json字符串寫入文件
 7 json.dump(dic, f)
 8 f.close()
 9 
10 f = open(json_file)
11 
12 # load方法接收一個文件句柄,直接將文件中的json字符串轉換成數據結構返回
13 dic2 = json.load(f)
14 f.close()
15 print(type(dic2), dic2)

    

    ensure_ascii關鍵字:默認是True,表示按照ascii的形式顯示,設置為False的時候,表是按照原來的文本樣式顯示(主要針對中文)
 1 import json
 2 
 3 f = open(file, w)
 4 json.dump({國籍: 中國}, f)
 5 ret = json.dumps({國籍: 中國})
 6 f.write(ret + \n)
 7 json.dump({國籍: 美國}, f, ensure_ascii=False)
 8 ret = json.dumps({國籍: 美國}, ensure_ascii=False)
 9 f.write(ret + \n)
10 f.close()
11 
12 # 寫到文件中的結果:
13 # {"\u56fd\u7c4d": "\u4e2d\u56fd"}{"\u56fd\u7c4d": "\u4e2d\u56fd"}
14 # {"????": "????"}{"????": "????"}(這裏是因為文件打開的模式不對)

(2) pickle 模塊

  pickle模塊提供了四個功能:dumps、dump(序列化,存)、loads(反序列化,讀)、load
  (不僅可以序列化字典,列表...可以把python中任意的數據類型序列化)
  pickle,用於python特有的類型 和 python的數據類型間進行轉換

  pickle--只能寫進去,不能追加

    示例1:

 1 import pickle
 2 
 3 dic = {k1: v1, k2: v2, k3: v3}
 4 str_dic = pickle.dumps(dic)
 5 print(str_dic)  # 一串二進制內容
 6 
 7 dic2 = pickle.loads(str_dic)
 8 print(dic2)  # 字典
 9 
10 # 結果:
11 # b‘\x80\x03}q\x00(X\x02\x00\x00\x00k1q\x01X\x02\x00\x00\x00v1q\x02X\x02\x00\x00\x00k2q\x03X\x02\x00\x00\x00v2q\x04X\x02\x00\x00\x00k3q\x05X\x02\x00\x00\x00v3q\x06u.‘
12 # {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, ‘k3‘: ‘v3‘}

    示例2:

 1 import time
 2 import pickle
 3 
 4 struct_time = time.localtime(1000000000)
 5 print(struct_time)
 6 
 7 f = open(pickle_file, wb)
 8 pickle.dump(struct_time, f)
 9 f.close()
10 
11 f = open(pickle_file, rb)
12 struct_time2 = pickle.load(f)
13 f.close()
14 
15 print(struct_time2.tm_year)
16 
17 
18 # 結果:
19 # time.struct_time(tm_year=2001, tm_mon=9, tm_mday=9, tm_hour=9, tm_min=46, tm_sec=40, tm_wday=6, tm_yday=252, tm_isdst=0)
20 # 2001

  json和pickle模塊對比:

    json,用於字符串 和 python數據類型間進行轉換
    pickle,用於python特有的類型 和 python的數據類型間進行轉換(可以把python中任意的數據類型序列化)

    json--能處理的很少
    pickle--可以序列化python裏沒有的,自己定義的數據類型

    json---是所有p編程語言通用的一種數據類型---網絡編程
    pickle---可以序列化一些自定義的數據類型---遊戲

(3)shelve---只提供了open 方法

   shelve也是python提供給我們的序列化工具,比pickle用起來更簡單一些。
shelve只提供給我們一個open方法,是用key來訪問的,使用起來和字典類似。
 1 import shelve
 2 
 3 f = shelve.open(shelve_file)
 4 f[key] = {int: 10, float: 9.5, string: Sample data}  # 直接對文件句柄操作,就可以存入數據
 5 f.close()
 6 
 7 import shelve
 8 
 9 f1 = shelve.open(shelve_file)
10 existing = f1[key]  # 取出數據的時候也只需要直接用key獲取即可,但是如果key不存在會報錯
11 f1.close()
12 print(existing)
13 
14 # 結果:
15 # {‘int‘: 10, ‘float‘: 9.5, ‘string‘: ‘Sample data‘}
    這個模塊有個限制,它不支持多個應用同一時間往同一個DB進行寫操作。
    所以當我們知道我們的應用如果只進行讀操作,可以讓shelve通過只讀方式打開DB
1 import shelve
2 
3 f = shelve.open(shelve_file, flag=r)
4 existing = f[key]
5 f.close()
6 print(existing)

    由於shelve在默認情況下是不會記錄待持久化對象的任何修改的,所以我們在shelve.open()時候需要修改默認參數,否則對象的修改不會保存。
 1 import shelve
 2 f1 = shelve.open(shelve_file)
 3 print(f1[key])
 4 f1[key][new_value] = this was not here before
 5 f1.close()
 6 
 7 f2 = shelve.open(shelve_file, writeback=True)
 8 print(f2[key])
 9 f2[key][new_value] = this was not here before
10 f2.close()
    writeback方式有優點也有缺點。優點是減少了我們出錯的概率,並且讓對象的持久化對用戶更加的透明了;
    但這種方式並不是所有的情況下都需要,
    首先,使用writeback以後,shelf在open()的時候會增加額外的內存消耗,並且當DB在close()的時候會將緩存中的每一個對象都寫入到DB,這也會帶來額外的等待時間。
    因為shelve沒有辦法知道緩存中哪些對象修改了,哪些對象沒有修改,因此所有的對象都會被寫入

    

Python之序列化模塊