Python編程:序列化和反序列化
前言
前面在學習時,簡單介紹了Python中的序列化和反序列化。我們已經知道,在程序運行的過程中,所有的變數都是在內存中,比如,定義一個dict:,我們可以隨時修改變數的值,比如把改成。但是一旦程序結束,變數所佔用的內存就被操作系統全部回收。如果沒有把修改後的存儲到磁碟上,下次重新運行程序,變數又被初始化為。
今天我們就來系統地學習Python中的序列化和反序列化。
序列化和反序列化
在python中,序列化可以理解為:把python的對象編碼轉換為json格式的字元串,反序列化可以理解為:把json格式字元串解碼為python數據對象。
我們把變數從內存中變成可存儲或傳輸的過程稱之為序列化,在Python中叫pickling,在其他語言中也被稱之為serialization,marshalling,flattening等等都是一個意思。序列化之後,就可以把序列化後的內容寫入磁碟,或者通過網路傳輸到別的機器上。反過來,把內容從序列化的對象重新讀到內存里稱之為反序列化,即unpickling。
在python的標準庫中,專門提供了json庫與pickle庫來處理這部分。
pickle模塊
使用pickle模塊,首先要導入該模塊:
把序列化後的內容存儲在變數中
返回結果是序列化後的位元組數據。
運行結果:
把序列化後的數據還原為對象(反序列化)
經過上面的序列化後,數據以位元組保存在了變數中,需要再次使用的時候使用函數就行了。如下:
運行結果:
直接存儲在文件中
上面的方法把任意對象序列化成一個,然後,就可以把這個寫入文件。或者用另一個方法直接把對象序列化後寫入一個,進行持久化。注意這次用的方法中少了個,即:,而不是上面用到的。
由於pickle寫入的是二進位數據,所以打開方式需要以和的模式。
運行結果:
直接把序列化後的內容寫入到文件中
也可以直接用方法從一個中直接反序列化出對象。如下:
運行結果:
這樣我們的數據就從文件中成功地反序列化到內存,保存到變數中了。要注意的是:這個變數和原來的變數是完全不相干的對象,它們只是內容相同而已。
序列化用戶自定義對象
開發中用的最多的就是我們自己定義類的對象,pickle當然也能寫入,不僅可以寫入類本身,也能寫入它的一個實例。
假設我們現在設計了一個類:
將類本身序列化到文件中:
運行結果:
將類本身序列化到文件中
將自定義類從文件中反序列化出來,並創建對象:
運行結果:
接下來,看下如何序列化自定義類的對象:
運行結果:(2處影響):
1.創建了文件,並寫入了序列化後的數據到該文件中。
創建了文件,並寫入了序列化後的數據
2.列印結果:
從文件中反序列化出對象:
運行結果:
上面演示了pickle模塊序列化和反序列化,兩套方法:序列化到文件並反序列化到變數的和序列化到文件並反序列化的。
json模塊
如果我們要在不同的編程語言之間傳遞對象,就必須把對象序列化為標準格式,比如XML,但更好的方法是序列化為JSON,因為JSON表示出來就是一個字元串,可以被所有語言讀取,也可以方便地存儲到磁碟或者通過網路傳輸。JSON不僅是標準格式,並且比XML更快,而且可以直接在Web頁面中讀取,非常方便。
提示:本質就是字元串,是一個特殊格式的字元串而已。
JSON表示的對象就是標準的JavaScript語言的對象,JSON和Python內置的數據類型對應如下:
Python內置的json模塊提供了非常完善的Python對象到JSON格式的轉換。我們先看看如何把Python對象變成一個JSON:
如果您有一個對象x,則可以使用一行簡單的代碼查看其JSON字元串表示:
運行結果:
提示:
1.使用前要先導入模塊,此處是方法,區別於方法。如果你遇到了下面錯誤,請檢查方法是否使用錯誤:
此文中用的python是3.5,在版本3.6中已更改:所有可選參數現在僅為關鍵字。
2.方法的另一個變體,只是將對象序列化為文本文件。
dumps()方法返回一個str,內容就是標準的JSON。類似的,dump()方法可以直接把JSON寫入一個file-like Object。
要把JSON反序列化為Python對象,用或者對應的方法,前者把JSON的字元串反序列化,後者從中讀取字元串並反序列化。
用反序列化
運行結果:
用反序列化
用反序列化,直接將文件反序列化為內存中的對象。
運行結果:
JSON進階
Python的等對象可以直接序列化為JSON的,不過,很多時候,我們更喜歡用表示對象,比如定義類,然後序列化:
運行結果:
解析:發現報錯了,錯誤的原因是對象不是一個可序列化為的對象。
查看該方法官方文檔,此文中用的python是3.5,在版本3.6中已更改:所有可選參數現在僅為關鍵字。
這些參數就是讓我們來定製JSON序列化。前面的代碼之所以無法把類實例序列化為,是因為默認情況下,方法不知道如何將實例變為一個的對象。
可選參數就是把任意一個對象變成一個可序列為的對象,我們只需要為專門寫一個轉換函數,再把函數傳進去即可:
我們再進行序列化時,就可以用到該函數了:
運行結果:
不過,下次如果遇到一個類的實例,照樣無法序列化為JSON。我們可以偷個懶,把任意class的實例變為dict,我們可以這麼干:
之所以可以這麼寫,是因為通常的實例都有一個屬性,它就是一個,用來存儲實例變數。要特別注意,也有少數例外,比如定義了的。
同樣的道理,如果我們要把反序列化為一個對象實例,方法首先轉換出一個對象,然後,我們傳入的函數負責把轉換為實例:
核心代碼:
運行結果:
列印出的是反序列化的實例對象:
以上是存儲到變數,存儲到文件也是類似操作。
小結
本小節系統地學習了python中如何序列化和反序列化。重點學習python的標準庫中的專門提供的:。
※符合 Python 風格的對象
※基於 Python 進行 App 伺服器端開發
TAG:Python |