1. 程式人生 > >Python之數據序列化(json、pickle、shelve)

Python之數據序列化(json、pickle、shelve)

編碼 att 傳輸 特殊 tro lose 進制 style 類型

什麽是序列化

什麽是序列化,把程序中的對象或者變量,從內存中轉換為可存儲或可傳輸的過程稱為序列化。在 Python 中,這個過程稱為 pickling,在其他語言中也被稱為 serialization,marshalling,flattening 等。程序中的對象(或者變量)在序列化之後,就可以直接存放到存儲設備上,或者直接發送到網絡上進行傳輸。

序列化的逆向過程,即為反序列化(unpickling),就是把序列化的對象(或者變量)重新讀到內存中~

Python中序列化的模塊

模塊名稱描述提供的api
json 用於實現Python數據類型與通用(json)字符串之間的轉換 dumps()、dump()、loads()、load()
pickle 用於實現Python數據類型與Python特定二進制格式之間的轉換 dumps()、dump()、loads()、load()
shelve 專門用於將Python數據類型的數據持久化到磁盤,shelve是一個類似dict的對象,操作十分便捷 open()

json模塊


大部分編程語言都會提供處理json數據的接口,Python 2.6開始加入了json模塊,且把它作為一個內置模塊提供,無需下載即可使用。

json支持的數據格式有限,有int str list dict

以及特殊的tuple(會將tuple轉為list)

Json模塊提供了四個功能:dumps、dump、loads、load

dumpsloads主要是在內存內操作,如下:

 import json
 
 list = [a,b,c]
 
 list_str = json.dumps(list)
 print(list_str)     #["a", "b", "c"]
 
 list2 = json.loads(list_str)
 print(list2)        #[‘a‘, ‘b‘, ‘c‘]

dumpload是從文件內操作,如下:

 import json
 
 list = [a,b,c]
 
 with open(test,w,encoding=utf-8) as f:
     json.dump(list,f)
 
 with open(test,r,encoding=utf-8) as f2:
     json.load(f2)

json模塊中的字符編碼問題

Python3中,代碼中的字符串都是使用 unicode 格式存放的,序列化之後也是以unicode 格式存放,所以序列化和反序列化過程都不存在問題。


Python2中,代碼中的字符串是 str類型,str類型 和 unicode類型 的關系如下所示:

unicode -----> encode --------> str(例如為 utf-8編碼)
utf-8(例如為 utf-8編碼) --------> decode ----------> unicode

所以在Python2中,序列化過程和反序列化過程都有涉及到轉碼過程(encode和decode),序列化過程 會先將對象中的字符串 使用utf-8 進行解碼(decode),轉換為unicode類型後,再存放到文件或者字符串中,反序列化過程 會將 json字符串 使用utf-8 編碼(encode),然後存放到內存中的變量~

pickle模塊


用法與json類似,不過pickle不能跨語言,優點是它支持python所有的數據類型

需要註意的是,pickle是以bytes類型來進行序列化的

import pickle
 
 list = [a,b,c]
 list_str = pickle.dumps(list)
 print(list_str)         #b‘\x80\x03]q\x00(X\x01\x00\x00\x00aq\x01X\x01\x00\x00\x00bq\x02X\x01\x00\x00\x00cq\x03e.‘
 
 list2 = pickle.loads(list_str)
 print(list2)            #[‘a‘, ‘b‘, ‘c‘]

而正因為pickle是以bytes類型進行序列化的,所以在用dump和load方法對文件進行寫入或者反序列化的時候,要以wb或者rb模式打開,如下:

import pickle
 
 list = [a,b,c]
 with open(test,wb) as f:
     pickle.dump(list,f)
 
 with open(test,rb) as f2:
     pickle.load(f2)

shelve模塊


shelve也是python提供給我們的序列化工具,比pickle用起來更簡單一些。 shelve只提供給我們一個open方法,是用key來訪問的,使用起來和字典類似

import shelve
  f = shelve.open(test1)
  f[key] = {a:1, b:2, c:sss}  #直接對文件句柄操作,就可以存入數據
  f[key2] = {d:3, e:4, f:ddd}
  f.close()
  
  f1 = shelve.open(test1)
  dic1 = f1[key]  #取出數據的時候也只需要直接用key獲取即可,但是如果key不存在會報錯
  dic2 = f1[key2]
 f1.close()
 print(dic1)
 print(dic2)

Python之數據序列化(json、pickle、shelve)