序列化和反序列化
為什麼要序列化
記憶體中的字典、清單、集合以及各種對象,如何儲存到一個檔案中?
如果是自己定義的類的執行個體,如何儲存在一個檔案中?
如何從檔案中讀取資料,并讓他們在記憶體中再次回複稱自己對應的類的執行個體?
要設計一套協定,按照某種規則進行轉換,轉換後的資料可以用來存儲或者傳輸。檔案是一個位元組序列,是以必須把資料轉換成位元組序列(可以害死),輸出到檔案。這就是序列化。反之從檔案的位元組序列恢複到記憶體并且還是原來的類型,這就是反序列化。
序列化協定的特點
- 跨平台,并有多語言支援。這是根本目的。
- 足夠流行,意味着使用者衆多,協定的基礎設施疊代更新快。
- 足夠成熟,意味着協定經過足夠的測試,和足夠時間的檢驗。
- 語言/平台的中立性,意味着協定對各個程式設計語言、作業系統的特性支援保持一緻。
- 可讀性,如果資料序列化之後的資料人眼可讀,那麼開發過程對序列化資料的調試就會變得非常簡單。
- 性能,為了保持原有的資料結構,資料在序列化的過程中,必然會加進額外的描述字段。加入額外的字段,必然會使序列化後的大小大于純資料的大小,同時也會涉及到序列化、反序列化對描述字段的解讀效率的問題。是以一個好的序列化協定,應該在空間複雜度和時間複雜度上有好的表現。
pickle庫
python中的序列化、反序列化子產品。
函數 | 說明 |
---|---|
dumps | 對象序列化為bytes對象 |
dump | 對象序列化到檔案對象 |
loads | 從bytes對象反序列化 |
load | 對象反序列化,從檔案讀取資料 |
序列化應用
一般來說本地序列化的應用很少,大多數場景都使用在網絡傳輸中。
将資料序列化通過網絡傳輸到遠端節點,遠端伺服器上的服務将接收到的資料反序列化後,就可以使用了。
但是要注意一點,遠端接收端,反序列時必須要有對應的資料類型,否則就會報錯。尤其是定義類 ,必須遠端得有一直的定義。
現在大多數項目都不是單機的,也不是單服務的,需要多個程式之間配合,需要通過網絡将資料傳送到其他節點上去,這就是大量的序列化、反序列化過程。
JSON
JSON起源于弱類型語言javascript,他的産生來自一種稱為"Associative array"的概念,其本質是就是采用"Attribute-value"的方式來描述對象。實際上在 Javascript 和 PHP 等弱類型語言中,類的描述方式就是 Associative array。JSON 的如下優點,使得它快速成為最廣泛使用的序列化協定之一。
json的優點:
1.這種 Associative array 格式非常符合工程師對對象的了解。
2.它保持了 XML 的人眼可讀(Human-readable)的優點。
3.相對于 XML 而言,序列化後的資料更加簡潔。 來自于的以下連結的研究表明:XML 所産生序列化之後檔案的大小接近 JSON 的兩倍。http://www.codeproject.com/Articles/604720/JSON-vs-XML-Some-hard-numbers-about-verbosity
4.它具備 Javascript 的先天性支援,是以被廣泛應用于 Web browser 的應用常景中,是 Ajax 的事實标準協定。
5.與 XML 相比,其協定比較簡單,解析速度比較快。
6.松散的 Associative array 使得其具有良好的可擴充性和相容性。
json子產品
python支援少量内建資料類型到json類型的轉換。
Python類型 | Json類型 |
---|---|
True | true |
False | false |
None | null |
string | string |
int | integer |
float | float |
list | array |
dict | object |
常用方法
Python類型 | Json類型 |
---|---|
dumps | json編碼序列化為json格式的str |
dump | json編碼序列化一個obj輸出到一個file-like對象 |
loads | 将一個包含json文檔的str、bytes或者bytearray反序列化為python對象 |
load | 将一個包含json文檔的textfile或者binaryfile反序列化為一個python對象 |
json的典型應用場景
json在很多場景中都可以替代XML,更簡潔并且解析速度更快
1.公司之間傳輸資料量較小,實時性要求較低的服務。
2.基于web browser的ajex
3.由于 JSON 具有非常強的前後相容性,對于接口經常發生變化,并對可調式性要求高的場景,例如 Mobile app 與服務端的通訊。
4.由于 JSON 的典型應用場景是 JSON+HTTP,适合跨防火牆通路。總的來說,采用 JSON 進行序列化的額外空間開銷比較大,對于大資料量服務或持久化,這意味着巨大的記憶體和磁盤開銷,這種場景不适合。沒有統一可用的 IDL 降低了對參與方的限制,實際操作中往往隻能采用文檔方式來進行約定,這可能會給調試帶來一些不便,延長開發周期。 由于 JSON 在一些語言中的序列化和反序列化需要采用反射機制,是以在性能要求為 ms 級别,不建議使用。
MessagePack
MessagePack是一個基于二進制高效的對象序列化類庫,可用于跨語言通信。
他可以像json那樣,在許多語言之間交換資料。
但是他比json更快速更輕巧。
它支援Python、Ruby、Java、C++等衆多語言。
相容json和pickle
常用方法
方法 | 含義 |
---|---|
packb | 序列化對象,提供了dumps來相容pickle和json |
unpackb | 反序列化對象。提供了loads來相容。 |
pack | 序列化對象到一個file-like對象,提供了dump來相容。 |
unpack | 反序列化file-like對象,提供了load來相容。 |
MessagePack簡單易用,高效壓縮,支援語言豐富。是以,用它序列化也是一種很好的選擇。
Python很多大名鼎鼎的庫都是用了msgpack
更多詳細内容可以參考下面連結
序列化和反序列化
pickle子產品官方文檔
www.json.org
msgpack.org