溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Python中序列化是什么

發(fā)布時(shí)間:2020-08-04 15:07:07 來(lái)源:億速云 閱讀:180 作者:清晨 欄目:編程語(yǔ)言

這篇文章將為大家詳細(xì)講解有關(guān)Python中序列化是什么,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

程序運(yùn)行時(shí),所有的變量都儲(chǔ)存在內(nèi)存中,程序結(jié)束運(yùn)行時(shí),這些占用的內(nèi)存將被系統(tǒng)回收,無(wú)法長(zhǎng)期儲(chǔ)存,將這些變量轉(zhuǎn)換為可儲(chǔ)存或可通過(guò)網(wǎng)絡(luò)傳輸?shù)倪^(guò)程稱(chēng)之為序列化(pickling),序列化后就可以將它們儲(chǔ)存在磁盤(pán)或通過(guò)網(wǎng)絡(luò)進(jìn)行傳輸。

1.pickle序列化

Python提供了pickle模塊來(lái)實(shí)現(xiàn)變量的序列化,這個(gè)模塊可以將變量轉(zhuǎn)換成字節(jié)碼(bytes)形式儲(chǔ)存,還能將儲(chǔ)存的序列化字節(jié)碼重新還原成數(shù)據(jù)對(duì)象;

注意:pickle僅能用于python程序之間交換數(shù)據(jù),且不同的版本之間并不兼容,需要和其他程序進(jìn)行通信時(shí),請(qǐng)使用json序列化,它可以在不同編程語(yǔ)言間共享數(shù)據(jù)。

a.pickle普通對(duì)象序列化

先來(lái)看一個(gè)小實(shí)例,使用pickle模塊,將幾個(gè)不同的對(duì)象序列化,這些序列化后的對(duì)象可用于網(wǎng)絡(luò)傳輸或儲(chǔ)存到磁盤(pán)文件中:

#!/usr/bin/env python3
#coding=utf-8
import os
import pickle
#創(chuàng)建一個(gè)字典對(duì)象和一個(gè)字符串對(duì)象
d=dict(one=1,two=2,three=3)
s="python"
print(d) #輸出{'three': 3, 'two': 2, 'one': 1}
print(s) #輸出
 
#將這兩個(gè)對(duì)象序列化,nd和ns僅保存在內(nèi)存中,可用于網(wǎng)絡(luò)傳輸
nd=pickle.dumps(d)
ns=pickle.dumps(s)
print(nd) #輸出字節(jié)碼"b'\x80\x03}q\x00...."
print(ns) #輸出字節(jié)碼"b'\x80\x03X\x11...."
 
#將序列化后的對(duì)象重新還原成數(shù)據(jù)(假設(shè)接收端接收到這些數(shù)據(jù)后,就能夠這樣還原)
nd=pickle.loads(nd)
ns=pickle.loads(ns)
print(nd) #輸出{'three': 3, 'two': 2, 'one': 1}
print(ns) #輸出
 
#創(chuàng)建一個(gè)文件testfile,接收字節(jié)碼(wb),將d對(duì)象中的數(shù)據(jù)寫(xiě)入其中,
#用于本地不同應(yīng)用程序之間數(shù)據(jù)交換(此時(shí)如果我們打開(kāi)testfile文件,
#就會(huì)看到一些類(lèi)似亂碼一樣的字符,實(shí)際上是d對(duì)象序列化后的數(shù)據(jù))
with open("testfile","wb") as f1:
    pickle.dump(d,f1)
 
#從testfile文件中讀取字節(jié)碼,還原成數(shù)據(jù)
if os.path.isfile("testfile"):
    with open("testfile","rb") as f2:
        print(f2.read()) #輸出"b'\x80\x03}q\x0...."
#因?yàn)樯弦徊阶x取了數(shù)據(jù),指針位置要重新設(shè)置成起始位置,
#這僅僅是為了演示給大家看,上面print和seek這兩句可以不寫(xiě)
        f2.seek(0)
        d=pickle.load(f2) #讀取f2中的數(shù)據(jù)還原
        print(d) #輸出{'three': 3, 'two': 2, 'one': 1}

總結(jié):僅在內(nèi)存中序列化和還原,使用dumps()和loads(),要將數(shù)據(jù)序列化后保存到文件中使用dump(),從文件中還原數(shù)據(jù)使用load(),兩者只有一個(gè)s的區(qū)別,注意不要混淆。

b.pickle類(lèi)序列化

有時(shí)候我們可能要傳輸或保存一個(gè)類(lèi)對(duì)象與其中所有的數(shù)據(jù),python中實(shí)現(xiàn)類(lèi)的序列化十分簡(jiǎn)單,與對(duì)象序列化沒(méi)有什么區(qū)別,請(qǐng)看下面的實(shí)例:

#!/usr/bin/env python3
#coding=utf-8
import pickle
########
class A:
    #--------
    def __init__(self,name="py",website="python"):
        self.name=name
        self.website=website
x=A()
x.name="晴刃"
 
#序列化類(lèi)實(shí)例x,可用于網(wǎng)絡(luò)傳輸
nx=pickle.dumps(x)
print(nx) #輸出"b'\x80\x03c__main__...."
 
#還原數(shù)據(jù)
nx=pickle.loads(nx)
print(nx) #輸出"<__main__.A object at 0x7f43c995c080>"
 
#將類(lèi)對(duì)象序列化后保存到磁盤(pán)文件中,可用于程序間數(shù)據(jù)交換
with open("testfile","wb") as f1:
    pickle.dump(x,f1)
 
#讀取文件中的數(shù)據(jù)還原
with open("testfile","rb") as f1:
    y=pickle.load(f1)
print(y.name) #輸出"晴刃"
print(y.website) #輸出

2.json序列化

如果要在不同的編程語(yǔ)言之間傳遞對(duì)象,可以使用python的json模塊對(duì)數(shù)據(jù)進(jìn)行序列化,json序列化后所有數(shù)據(jù)都被表示成字符串形式,可以被所有語(yǔ)言讀取,也可以方便地存儲(chǔ)到磁盤(pán)或者通過(guò)網(wǎng)絡(luò)傳輸,但在類(lèi)數(shù)據(jù)轉(zhuǎn)換時(shí)會(huì)稍微有點(diǎn)麻煩,沒(méi)有pickle那么方便。

a.json普通對(duì)象序列化

#!/usr/bin/env python3
#coding=utf-8
import json
 
#創(chuàng)建一個(gè)字典對(duì)象和一個(gè)浮點(diǎn)數(shù)對(duì)象
d=dict(one=1,two=2,three=3)
f=3.14
 
print(type(d)) #<class 'dict'>
print(type(f)) #<class 'float'>
 
#普通對(duì)象的序列化與pickle相同
nd=json.dumps(d)
nf=json.dumps(f)
 
#轉(zhuǎn)換后所有對(duì)象都變成了字符串類(lèi)型<class 'str'>
print(type(nd))
print(type(nf))
print(nd) #"{"three": 3, "two": 2, "one": 1}"
print(nf) #"3.14"
 
#還原數(shù)據(jù)
nd=json.loads(nd)
nf=json.loads(nf)
print(type(nd)) #<class 'dict'>
print(type(nf)) #<class 'float'>
 
#將d對(duì)象序列化后儲(chǔ)存到testfile文件中
with open("testfile","w") as f1:
    json.dump(d,f1)
 
#從testfile文件中讀取數(shù)據(jù)并還原
with open("testfile","r") as f1:
    y=json.load(f1)
    print(type(y)) #<class 'dict'>

b.json類(lèi)序列化

使用json序列化類(lèi)會(huì)稍顯復(fù)雜,因?yàn)閖son的dump方法不知道如何將一個(gè)類(lèi)轉(zhuǎn)換成字符串,需要我們自己指定一個(gè)轉(zhuǎn)換函數(shù),請(qǐng)看下面的實(shí)例:

#!/usr/bin/env python3
#coding=utf-8
import json
 
class A(object):
    def __init__(self,name="py",website="python"):
        self.name=name
        self.website=website
#初始化一個(gè)類(lèi)實(shí)例
a=A()
 
#創(chuàng)建一個(gè)函數(shù),將類(lèi)A中的對(duì)象和數(shù)據(jù)轉(zhuǎn)換成字典的形式返回
def  classA2dict(c):
    return {"name":c.name,"website":c.website}
 
#將a使用json序列化,參數(shù)default告訴python解釋器,將前面的對(duì)象a傳遞給后面的classA2dict函數(shù)處理,
#classA2dict函數(shù)會(huì)返回一個(gè)字典類(lèi)型,這個(gè)類(lèi)型中包含了實(shí)例a中所有對(duì)象和數(shù)據(jù)的"鍵值對(duì)",
#然后dumps函數(shù)將這個(gè)返回的字典類(lèi)型序列化成字符串類(lèi)型
x=json.dumps(a,default=classA2dict)
#如果想偷懶不寫(xiě)classA2dict函數(shù),有一種簡(jiǎn)便方法,使用匿名函數(shù),并且調(diào)用基類(lèi)的__dict__函數(shù),
#這個(gè)函數(shù)會(huì)完成和classA2dict函數(shù)相同的功能,即將一個(gè)類(lèi)的所有屬性轉(zhuǎn)換成字典"鍵值對(duì)"的形式
#x=json.dumps(a,default=lambda obj:obj.__dict__)
 
print(type(x)) #<class 'str'>
print(x) #"{"website": "python", "name": "py"}"
 
#字典類(lèi)型轉(zhuǎn)換成類(lèi)返回
def dict2classA(d):
    return A(d["name"],d["website"])
 
#將json序列后的數(shù)據(jù)還原成類(lèi),object_hook參數(shù)將x轉(zhuǎn)換成字典類(lèi)型,并傳遞給dict2classA函數(shù)處理,
#dict2classA函數(shù)會(huì)讀取這個(gè)字典中的每個(gè)鍵,將值傳入A類(lèi)進(jìn)行初始化,返回一個(gè)類(lèi)對(duì)象
x=json.loads(x,object_hook=dict2classA)
print(type(x)) #<class '__main__.A'>
print(x.website) 
 
#將序列化的類(lèi)寫(xiě)入文件testfile中
with open("testfile","w") as f1:
    json.dump(a,f1,default=classA2dict)
#讀取testfile中的數(shù)據(jù)還原
with open("testfile","r") as f2:
    y=json.load(f2,object_hook=dict2classA)
    print(y.name)

關(guān)于Python中序列化是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI