python 序列化和反序列化

一 概述

1 爲何要序列化

由於TCP/IP協議只支持字節數組的傳輸,不能直接傳對象。對象序列化的結果必定是字節數組!當兩個進程在進行遠程通訊時,彼此能夠發送各類類型的數據。不管是何種類型的數據,都會以二進制序列的形式在網絡上傳送。發送方須要把這個對象轉換爲字節序列,才能在網絡上傳送;接收方則須要把字節序列再恢復爲對象。python

2 序列化和反序列化

序列化(serialization):及有序的列,數據轉換成二進制的有序的過程
協議:規定序列化和反序列化的轉換方式及就是把數據保存成二進制存儲起來,其是定義的規則,其規則稱爲協議若是規定了協議,則能夠進行序列化和反序列化,其協議是由版本的,約定協議後進行處理 mysql

反序列化(deserialization):將有序的二進制序列轉換成某種對象(字典,列表等)稱爲反序列化 sql

持久化:序列化保存到文件就是持久化,序列化未必會持久化,序列化每每是傳輸或存儲。能夠將數據序列化後持久化,或者網絡傳輸,也能夠將從文件或網絡接受到的字節序列反序列化。編程

二 python pickle

1 概述

pickle python中的序列化,反序列化模塊,其侷限是僅限於傳輸的兩端都是python的狀況,且儘可能保持兩端的版本一致json

2 pickle 庫基本方法

dumps 對象序列化,在內存中
dump 對象序列化到文件對象,就是存入文件
loads 對象反序列化
load 對象反序列化,從文件中讀取數據 數組

3 實例

#!/usr/local/bin/python3.6
#coding:utf-8
from  pickle import  *
from  pathlib  import Path
lst='a b c d'.split()  #返回一個列表
d=dict(zip('abcd',range(4)))  #構建一個字典
print (lst,d)  # 打印字典和列表
p=Path('/root/test.py')
if not  p.parent.exists():  # 建立文件的上級目錄
    p.parent.mkdir(parents=True)
with  open(p,'wb+')   as  f:  #進行序列化,必須是二進制的輸入,不然會報錯
    dump(lst,f)
    dump(d,f)
with  open(p,'rb')  as  f: #此處對應的是二進制的輸出
    print (load(f))
    print  (load(f))

結果以下ruby

python 序列化和反序列化

#!/usr/local/bin/python3.6
#coding:utf-8
from  pickle import  *
from  pathlib  import Path
d=dict(zip('mysql',range(5)))
s=dumps(d)  #進行序列化
print  (s)  # 正常狀況的輸出
print (loads(s))  # 進行反序列化並輸出

結果以下
python 序列化和反序列化服務器

切換3.5環境進行查看處理
python 序列化和反序列化網絡

對類的處理編程語言

#!/usr/local/bin/python3.6
#coding:utf-8
from  pickle import  *
from  pathlib  import Path
class  A():  #建立一個類
    def show(self):
        print ('aaaa')
a=A()  # 對類進行實例化
with  open('/root/test1.py','wb+')  as  f:  # 將實例化後的類的對象使用序列化寫入到文件中
    dump(a,f)
with  open('/root/test1.py','rb')  as  f: # 將對象的結果進行查看
    x=load(f)
    x.show()

結果以下

python 序列化和反序列化

python 序列化和反序列化

#!/usr/local/bin/python3.6
#coding:utf-8
from  pickle import  *
from  pathlib  import Path
class  A():  #建立一個類
    def show(self):
        print ('aaaa')
        print  ('bbbbb')
a=A()  # 對類進行實例化
with  open('/root/test1.py','wb+')  as  f:  # 將實例化後的類的對象使用序列化寫入到文件中
    dump(a,f)
with  open('/root/test1.py','rb')  as  f: # 將對象的結果進行查看
    x=load(f)
    x.show()  # 調用類的方法

查看結果
python 序列化和反序列化
寫入的數據以下
python 序列化和反序列化

此處寫入的數據未發生改變,但其在類中增長了數據,此處記錄的是模塊名和類名。若在不一樣的平臺進行操做,則會報錯

切換3.5環境,報錯,由於其中沒有這個test的模塊名沒有對應的classA,所以會報錯。

python 序列化和反序列化

對象序列化

#!/usr/local/bin/python3.6
#coding:utf-8
from  pickle import  *
from  pathlib  import Path
class  A():  #建立一個類
    def __init__(self): #對類進行初始化的操做,及就是在對象賦值時,此類會被帶入其中
        self.tttt='abcdf'
a=A()  # 對類進行實例化
with  open('/root/test1.py','wb+')  as  f:  # 將實例化後的類的對象使用序列化寫入到文件中
    dump(a,f)
with  open('/root/test1.py','rb')  as  f: # 將對象的結果進行查看
    x=load(f)
    print (x.tttt)  # 調用類的方法

查看以下
python 序列化和反序列化
查看寫入數據,其發生了變化

python 序列化和反序列化
但其切換環境,仍是不能找到
python 序列化和反序列化

4 總結

RPC 雛形:
遠程過程調用: 及遠程調用某個模塊的函數來實現其過程的調用 ,必需要保證遠程的函數和本地須要的函數一致而且必須存在,不然會報錯
經過網絡傳輸,不須要持久化,進行類的一致性
對於非自定義類,兩邊一致,不須要,如果自定義類,則須要兩端保持一致


應用:
本地序列化的狀況,應用較少
通常來講,大多數應用場景在網絡中,將數據序列化後經過網絡傳輸到遠程結點,遠程服務器上的服務接受到數據後進行反序列化,就可使用了。
可是,須要注意的是,遠端接受端,反序列化時必須有對應的數據類型,不然就會報錯,尤爲是自定義類,必須遠程存在


目前,大多數項目都不是單機,不是單服務,須要經過網絡將數據傳送到其餘結點上,這就須要大量的序列化,反序列化。
可是python程序之間還可使用pickple解決序列化,反序列化,若是是跨平臺,跨語言,跨協議pickle就不適合了,就須要公共協議,如XML/Json /protocol Buffer等。
每種協議都有本身的負載,其所使用的場景都不同,二進制的操做不必定適用於全部的場景。但越是底層的協議,越須要二進制傳輸

三 JSON

1 概述

JSON(JavaScript object notation,JS 對象標記)是一種輕量級的數據交換格式,它基於ECMAscript(w3c制定的JS規範)的一個子集,採用徹底獨立於編程語言的文本格式來存儲和表示數據

2 JSON的數據類型

其key必須是字符串,其值能夠是下面類型

雙引號引發來的字符串,數值,true和false,null(None),對象(字典),數組(列表)這些都是值

python 序列化和反序列化
此處表示了JSON值支持的數據類型

1 string:

字符串,由雙引號包圍起來的任意字符的組合,能夠有轉義字符


2 number :
數值,有正負數,整數,浮點數


3 對象:
無序的鍵值對集合
格式:{key1:value1,...keyn:valuen}
key 必須是字符串,須要使用雙引號包圍這個字符串,value能夠是任意合法的值

python 序列化和反序列化

其表示要麼是{},要麼有key,value,若key:value完成,則後面不能有逗號,一旦有逗號,則表示後面還有數據


4 數組 :
python 序列化和反序列化

同上,一旦有逗號,則表示後面還有數據

python 序列化和反序列化

此處的問題是,其json文件的鍵是非字符串,其值的字符串不是使用雙引號括起來的,所以其會出現報錯的狀況


5 null 至關於python的None


6 布爾型 false(False) true(True)

3 經常使用方法

dumps json 編碼
dump json 編碼並存入文件
loads json 解碼
load json 解碼,從文件讀取數據

4 應用

#!/usr/local/bin/python3.6
#coding:utf-8
from json  import *
d={'a':1,'b':{'c':{'d':[1,23,4,5]}},'e':None,'f':True,'g':False}  #構造字典
print (d)  # 輸出字典
print  (dumps(d))  #對字典對象進行序列化
print (loads((dumps(d))))  # 對結果進行反序列化

結果以下
python 序列化和反序列化

#!/usr/local/bin/python3.6
#coding:utf-8
from json  import *
class  A():  # 建立一個類
    def  show(self):
        return  'mysql'
print (dumps(A().show()))  # 對類進行實例化並調用其方法返回結果進行序列化
print (loads(dumps(A().show())))  # 對其進行反序列化

結果以下
python 序列化和反序列化

通常的json編碼的數據不多落地,數據都是經過網絡傳輸,傳輸的時候,要考慮壓縮它,本質上來講它就是一個文本,一個字符串,json很普遍,幾乎全部的編程語言都支持它。

四 messagepack(第三方庫)

1 概述

messagepack 是一個基於二進制高效的對象序列化類庫,可用於跨語言通訊,其能夠像JSON那樣,在許多語言之間交換結構對象,可是其比JSON更快速更輕巧。其支持python,ruby,Java,C/C++等衆多語言,兼容JSON和pickle

2 安裝

pip install msgpack-python

3 經常使用方法

packb 序列化對象,提供了dumps來兼容pickle和json
unpackb 反序列化對象,提供了loads來兼容

pack序列化對象保存到文件對象,提供了dump來兼容
unpack 反序列化對象保存到文件對象,提供了load來兼容

4 基本應用

#!/usr/local/bin/python3.6
#coding:utf-8
from  msgpack  import  *
import  sys
d={'a':1234,'b':['abc',{'c':234}],'d':True,'e':False,'f':None}  # 構建一個字典
b=packb(d)  # 進行序列化操做
print (b) # 打印
print (unpackb(b))  #進行反序列化操做
print (unpackb(b,encoding='utf-8'))  #經過制定編碼方式輸出

結果以下
python 序列化和反序列化

相關文章
相關標籤/搜索