python全棧開發-json和pickle模塊(數據的序列化)
一、什麽是序列化?
我們把對象(變量)從內存中變成可存儲或傳輸的過程稱之為序列化,在Python中叫pickling,在其他語言中也被稱之為serialization,marshalling,flattening等等,都是一個意思。
為什麽要序列化?
1、持久保存狀態
需知一個軟件/程序的執行就在處理一系列狀態的變化,在編程語言中,‘狀態‘會以各種各樣有結構的數據類型(也可簡單的理解為變量)的形式被保存在內存中。
內存是無法永久保存數據的,當程序運行了一段時間,我們斷電或者重啟程序,內存中關於這個程序的之前一段時間的數據(有結構)都被清空了。
在斷電或重啟程序之前將程序當前內存中所有的數據都保存下來(保存到文件中),以便於下次程序執行能夠從文件中載入之前的數據,然後繼續執行,這就是序列化。
具體的來說,如,虛擬機狀態的掛起等。
2、跨平臺數據交互
序列化之後,不僅可以把序列化後的內容寫入磁盤,還可以通過網絡傳輸到別的機器上,如果收發的雙方約定好實用一種序列化的格式,那麽便打破了平臺/語言差異化帶來的限制,實現了跨平臺數據交互。
反過來,把變量內容從序列化的對象重新讀到內存裏稱之為反序列化,即unpickling。
如果我們要在不同的編程語言之間傳遞對象,就必須把對象序列化為標準格式,比如XML,但更好的方法是序列化為JSON,因為JSON表示出來就是一個字符串,可以被所有語言讀取,也可以方便地存儲到磁盤或者通過網絡傳輸。JSON不僅是標準格式,並且比XML更快,而且可以直接在Web頁面中讀取,非常方便。
JSON表示的對象就是標準的JavaScript語言的對象,JSON和Python內置的數據類型對應如下:
二、json序列化
1、dumps序列化和loads反序列化
dumps()序列化
import json #導入json模塊 info = { ‘name‘:"qianduoduo", "age":22, } with open("test.json","w") as f: #以普通模式寫入 f.write(json.dumps(info)) #把內存對象轉為字符串 #寫到文件中 #test.json文件中的內容{"name": "qianduoduo", "age": 22}
loads()反序列化
import json #導入json模塊 with open("test.json","r") as f: #以普通模式讀 data = json.loads(f.read()) #用loads反序列化 print(data["age"]) #date.get("age") 一樣的 #輸出 22
2、dump序列化和load反序列化
dump()序列化
import json info = { ‘name‘:"qianduoduo", "age":22 } with open("test.json","w") as f: #文件以寫的方式打開 json.dump(info,f) #第1個參數是內存的數據對象 ,第2個參數是文件句柄 #test.json文件中的內容 {"name": "qianduoduo", "age": 22}
load()反序列化
import json with open("text.txt","r") as f: #以讀的方式打開文件 data = json.load(f) #輸入文件對象 print(data.get("age")) #date["age"] #輸出 22
3、序列化函數(不支持的,直接報錯)
總結:
1、dumps和loads是成對使用的,dump和load是成對使用的。
2、dumps和loads由於序列化的是內容,所以後面要加s,但是dump和load序列化的內容是對象,所以單數。
3、json只能處理簡單的數據類型,例如:字典、列表、字符串等,不能處理函數等復雜的數據類型。
為什麽不能處理復雜的因為python 和別的語言定義函數,類完全不一樣,特性也不一樣
4、json是所有語言通用的,所有語言都支持json,如果我們需要python跟其他語言進行數據交互,那麽就用json格式。
三、pickle序列化
1、dumps序列化和loads反序列化
dumps()序列化
import pickle info = { ‘name‘:"qianduoduo", "age":22, } with open("test.json","wb") as f: #以二進制的形式寫入 data = pickle.dumps(info) #序列化成字符串 f.write(data) #寫入text.txt 文件中 #輸出到test.json文件中的內容 我們看不懂的二級制 ?}q (X nameqX qianduoduoqX ageqKu.
loads()反序列化
import pickle with open("text.txt","rb") as f: #以二進制的模式讀 data = pickle.loads(f.read()) #反序列化操作 print(data.get("age")) #date["age"] 是一樣的 #輸出 22
2、dump序列化和load反序列化
dump()序列化
import pickle info = { ‘name‘:"qianduoduo", "age":22, } with open("text.txt","wb") as f: pickle.dump(info,f) #序列化 #輸出 ?}q (X nameqX qianduoduoqX ageqKu.
load()反序列化
import pickle with open("text.txt","rb") as f: data = pickle.load(f) #反序列化成內存對象 print(data.get("age")) #or date["age"] 一樣的 #輸出 22
3、序列化函數
序列化
import pickle def sayhi(name): #函數 print("hello:",name) info = { ‘name‘:"duoduo", "age":22, "func":sayhi #"func"對應的值sayhi,是函數名 如果sayhi加()就執行這個函數 } with open("test.json","wb") as f: data = pickle.dumps(info) f.write(data) #輸出test.json ?}q (X nameqX qianduoduoqX ageqKX funcqc__main__ sayhi
反序列化
import pickle def sayhi(name): #在反序列化中必須寫上此函數,不然會報錯,因為在加載的時候,函數沒有加載到內存 print("hello:",name) with open("test.json","rb") as f: data = pickle.loads(f.read()) print(data["age"]) data.get("func")("qianduoduo") #執行函數sayhi #輸出 22 hello: qianduoduo #輸出的函數體中的邏輯也是可以變的,但是函數名必須要相同,這又是要註意的地方
小結:
1、json值支持簡單的數據類型,pickle支持python所有的數據類型。
2、pickle只能支持python本身的序列化和反序列化,不能用作和其他語言做數據交互,而json可以。
3、pickle序列化的是整個的數據對象,所以反序列化函數時,函數體中的邏輯變了,是跟著新的函數體邏輯。
4、pickle和json在3.0中只能dump一次和load一次,dump在2.7裏面可以dump多次,load多次,anyway,以後只記住,只需要dump一次,load一次就可以了。
Pickle的問題和所有其他編程語言特有的序列化問題一樣,就是它只能用於Python,並且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的數據,不能成功地反序列化也沒關系。
python全棧開發-json和pickle模塊(數據的序列化)