1. 程式人生 > >python全棧開發-json和pickle模塊(數據的序列化)

python全棧開發-json和pickle模塊(數據的序列化)

簡單的 flat ria ati rip 我們 dex 保存狀態 png

一、什麽是序列化?

  我們把對象(變量)從內存中變成可存儲或傳輸的過程稱之為序列化,在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模塊(數據的序列化)