溫馨提示×

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

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

21文件IO_pickle

發(fā)布時(shí)間:2020-06-24 00:44:48 來(lái)源:網(wǎng)絡(luò) 閱讀:287 作者:chaijowin 欄目:編程語(yǔ)言

?

序列化、反序列化:

為什么要序列化?

內(nèi)存中的字典、鏈表如何保存到一個(gè)文件中?

如果是自己定義的類(lèi)的實(shí)例,如何保存到一個(gè)文件中?

如何從文件中讀取數(shù)據(jù),并讓它們?cè)趦?nèi)存中再次變成自己對(duì)應(yīng)的類(lèi)的實(shí)例?

?

要設(shè)計(jì)一套協(xié)議(協(xié)議有版本,不同版本有不同的實(shí)現(xiàn),規(guī)則不一樣),按照某種規(guī)則,把內(nèi)存中數(shù)據(jù)保存到文件中,文件是一個(gè)字節(jié)序列,所以必須把數(shù)據(jù)轉(zhuǎn)換成字節(jié)序列,輸出到文件,這就是序列化;反之,從文件的字節(jié)序列恢復(fù)到內(nèi)存,就是反序列化;

?

數(shù)據(jù)轉(zhuǎn)換成二進(jìn)制的有序序列的過(guò)程,稱為序列化;

從文件(有序的二進(jìn)制序列)轉(zhuǎn)換成某種對(duì)象(list、dict等)的過(guò)程,稱為反序列化;

?

serialization序列化,將內(nèi)存中對(duì)象存儲(chǔ)下來(lái),把它變成一個(gè)個(gè)字節(jié)(二進(jìn)制);

deserialization反序列化,將文件的一個(gè)個(gè)字節(jié)(二進(jìn)制)恢復(fù)成內(nèi)存中的對(duì)象;

?

注:

持久化,存在磁盤(pán)中,掉電不丟失;

序列化保存到文件,就是持久化;

可以將數(shù)據(jù)序列化后持久化(持久化前一定要序列化),或者網(wǎng)絡(luò)傳輸(通常big-edian模式),也可以從文件中或網(wǎng)絡(luò)接收到的字節(jié)序列反序列化;

每一種高級(jí)語(yǔ)言都有自己的序列化;

異構(gòu)平臺(tái),兩端,如c/c++<-->python,要約定協(xié)議規(guī)定等;

?

?

?

python提供了pickle庫(kù):

pickle僅限網(wǎng)絡(luò)兩端都是python程序;

import pickle

pickle.dumps(obj,protocol,fix_imports),對(duì)象序列化,不落地,在內(nèi)存中操作;

pickle.dump(obj,protocol,fix_imports),對(duì)象序列化到文件對(duì)象,存入文件;

pickle.loads(data,fix_imports,encoding,errors),對(duì)象反序列化,從內(nèi)存加載;

pickle.load(file,fix_imports,encoding,errors),對(duì)象反序列化,從文件讀取數(shù)據(jù);

?

內(nèi)建類(lèi)型list、dict等,兩邊定義一致;

類(lèi)、類(lèi)屬性、類(lèi)方法,僅序列化類(lèi)名,兩端若類(lèi)定義不一致,在調(diào)用后會(huì)有問(wèn)題

對(duì)象屬性相關(guān)的,會(huì)序列化;而類(lèi)方法、類(lèi)屬性不會(huì)序列化(僅序列化類(lèi)名)

?

總結(jié):

反序列化時(shí),類(lèi)是棋子,二進(jìn)制序列就是鐵水;

類(lèi)似,中央發(fā)往各州縣的錢(qián)模;適合分布式;

?

rpc,遠(yuǎn)程過(guò)程調(diào)用原型;在網(wǎng)絡(luò)編程中極為重要,底層要實(shí)現(xiàn)的就是序列化、反序列化;

dict、list為內(nèi)建的類(lèi);

通常需要自定義類(lèi),兩邊的自定義要一致;

自定義的序列化要作校驗(yàn);

?

應(yīng)用:

本地序列化的情況,應(yīng)用較少;

一般來(lái)說(shuō),大多數(shù)場(chǎng)景都應(yīng)用在網(wǎng)絡(luò)中,將數(shù)據(jù)序列化后通過(guò)網(wǎng)絡(luò)傳輸?shù)竭h(yuǎn)程節(jié)點(diǎn),遠(yuǎn)程服務(wù)器上的服務(wù)接收到數(shù)據(jù)將其反序列化,就可使用了;

但,要注意,遠(yuǎn)程接收端,反序列化時(shí),必須有對(duì)應(yīng)的數(shù)據(jù)類(lèi)型,否則會(huì)報(bào)錯(cuò),尤其是自定義類(lèi)等,遠(yuǎn)程必須要有;

兩端python環(huán)境要一致;是推到遠(yuǎn)端,不是遠(yuǎn)端來(lái)拉;

現(xiàn)在,大多數(shù)項(xiàng)目,都不是單機(jī)的,也不是單服務(wù)的,需要通過(guò)網(wǎng)絡(luò)將數(shù)據(jù)傳送到其節(jié)點(diǎn)上,這就需要大量的序列化和反序列化;

python程序間可用pickle解決序列化、反序列化;

如果是跨平臺(tái),跨語(yǔ)言、跨協(xié)議,pickle就不太適合了,就需要公共的協(xié)議,如xmljson、protocol bufferglogle)等;

不同的協(xié)議,效率不同,學(xué)習(xí)曲線不同,適用不同場(chǎng)景,要根據(jù)不同的情況分析選型;

?

例(內(nèi)建類(lèi)型listdict等,兩邊定義一致):

import pickle

?

lst = 'a b c'.split()

d = dict(zip('abc',range(3)))

?

with open('/home/python/magedu/projects/cmdb/bin','wb') as f:

??? pickle.dump(lst,f)

??? pickle.dump(d,f)

?

with open('/home/python/magedu/projects/cmdb/bin','rb') as f:

??? tmp = pickle.load(f)

??? print(type(tmp))

??? print(tmp)

??? tmp = pickle.load(f)

??? print(tmp)

注:

運(yùn)行結(jié)果:

<class 'list'>

['a', 'b', 'c']

{'a': 0, 'b': 1, 'c': 2}

bin文件放至win上;

21文件IO_pickle

?21文件IO_pickle

例(類(lèi)、類(lèi)屬性、類(lèi)方法,僅序列化類(lèi)名,兩端若類(lèi)定義不一致,在調(diào)用后會(huì)有問(wèn)題):

import pickle

?

class AA:

??? def show(self):

??????? print('abc')

?

aa = AA()

?

with open('/home/python/magedu/projects/cmdb/bin2','wb') as f:

??? pickle.dump(aa,f)

?

with open('/home/python/magedu/projects/cmdb/bin2','rb') as f:

??? tmp = pickle.load(f)?? #重新實(shí)例化后,賦給tmp,和aa是不同的對(duì)象

??? tmp.show()

注:

運(yùn)行結(jié)果:

abc

bin2傳至win主機(jī):

21文件IO_pickle

21文件IO_pickle

linuxwin下,兩端若定義的AA不一樣,則有問(wèn)題;

?

例(類(lèi)、類(lèi)屬性、類(lèi)方法,僅序列化類(lèi)名,兩端若類(lèi)定義不一致,在調(diào)用后會(huì)有問(wèn)題):

import pickle

?

class AA:

??? cccc = 'abc'?? #類(lèi)屬性

??? def show(self):

??????? print('abcd')

?

with open('bin3','wb') as f:

??? pickle.dump(AA(),f)

?

with open('bin3','rb') as f:

??? t = pickle.load(f)

??? t.show()

??? print(t.cccc)

注:

運(yùn)行結(jié)果:

abcd

abc

bin3傳至win主機(jī):

21文件IO_pickle

21文件IO_pickle

?

例(對(duì)象屬性相關(guān)的,會(huì)序列化;而類(lèi)方法、類(lèi)屬性不會(huì)序列化(僅序列化類(lèi)名)):

import pickle

?

class AA:

??? def __init__(self):

??????? self.aa = 'cc'?? #對(duì)象屬性,每個(gè)對(duì)象是獨(dú)立的,每個(gè)對(duì)象可改變此處定義

?

with open('bin4','wb') as f:

??? pickle.dump(AA(),f)

?

with open('bin4','rb') as f:

??? t = pickle.load(f)

??? print(t.aa)

注:

運(yùn)行結(jié)果:

cc

bin4傳至win主機(jī):

21文件IO_pickle

21文件IO_pickle

?

?


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

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎ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