最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

12.4 序列化

2021-09-28 08:41 作者:海鷗之道  | 我要投稿

在程序運(yùn)行的過(guò)程中,所有的變量都是在內(nèi)存中,比如,定義一個(gè)dict:

可以隨時(shí)修改變量,比如把name改成'Bill',但是一旦程序結(jié)束,變量所占用的內(nèi)存就被操作系統(tǒng)全部回收。如果沒(méi)有把修改后的'Bill'存儲(chǔ)到磁盤(pán)上,下次重新運(yùn)行程序,變量又被初始化為'Bob'

我們把變量從內(nèi)存中變成可存儲(chǔ)或傳輸?shù)倪^(guò)程稱(chēng)之為序列化,在Python中叫pickling,在其他語(yǔ)言中也被稱(chēng)之為serialization,marshalling,flattening等等,都是一個(gè)意思。

序列化之后,就可以把序列化后的內(nèi)容寫(xiě)入磁盤(pán),或者通過(guò)網(wǎng)絡(luò)傳輸?shù)絼e的機(jī)器上。

反過(guò)來(lái),把變量?jī)?nèi)容從序列化的對(duì)象重新讀到內(nèi)存里稱(chēng)之為反序列化,即unpickling。

Python提供了pickle模塊來(lái)實(shí)現(xiàn)序列化。

首先,我們嘗試把一個(gè)對(duì)象序列化并寫(xiě)入文件:

pickle.dumps()方法把任意對(duì)象序列化成一個(gè)bytes,然后,就可以把這個(gè)bytes寫(xiě)入文件?;蛘哂昧硪粋€(gè)方法pickle.dump()直接把對(duì)象序列化后寫(xiě)入一個(gè)file-like Object:

看看寫(xiě)入的dump.txt文件,一堆亂七八糟的內(nèi)容,這些都是Python保存的對(duì)象內(nèi)部信息。

當(dāng)我們要把對(duì)象從磁盤(pán)讀到內(nèi)存時(shí),可以先把內(nèi)容讀到一個(gè)bytes,然后用pickle.loads()方法反序列化出對(duì)象,也可以直接用pickle.load()方法從一個(gè)file-like Object中直接反序列化出對(duì)象。我們打開(kāi)另一個(gè)Python命令行來(lái)反序列化剛才保存的對(duì)象:

變量的內(nèi)容又回來(lái)了!

當(dāng)然,這個(gè)變量和原來(lái)的變量是完全不相干的對(duì)象,它們只是內(nèi)容相同而已。

Pickle的問(wèn)題和所有其他編程語(yǔ)言特有的序列化問(wèn)題一樣,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的數(shù)據(jù),不能成功地反序列化也沒(méi)關(guān)系。

JSON

如果我們要在不同的編程語(yǔ)言之間傳遞對(duì)象,就必須把對(duì)象序列化為標(biāo)準(zhǔn)格式,比如XML,但更好的方法是序列化為JSON,因?yàn)镴SON表示出來(lái)就是一個(gè)字符串,可以被所有語(yǔ)言讀取,也可以方便地存儲(chǔ)到磁盤(pán)或者通過(guò)網(wǎng)絡(luò)傳輸。JSON不僅是標(biāo)準(zhǔn)格式,并且比XML更快,而且可以直接在Web頁(yè)面中讀取,非常方便。

JSON表示的對(duì)象就是標(biāo)準(zhǔn)的JavaScript語(yǔ)言的對(duì)象,JSON和Python內(nèi)置的數(shù)據(jù)類(lèi)型對(duì)應(yīng)如下:

Python內(nèi)置的json模塊提供了非常完善的Python對(duì)象到JSON格式的轉(zhuǎn)換。我們先看看如何把Python對(duì)象變成一個(gè)JSON:

dumps()方法返回一個(gè)str,內(nèi)容就是標(biāo)準(zhǔn)的JSON。類(lèi)似的,dump()方法可以直接把JSON寫(xiě)入一個(gè)file-like Object。

要把JSON反序列化為Python對(duì)象,用loads()或者對(duì)應(yīng)的load()方法,前者把JSON的字符串反序列化,后者從file-like Object中讀取字符串并反序列化:

由于JSON標(biāo)準(zhǔn)規(guī)定JSON編碼是UTF-8,所以我們總是能正確地在Python的str與JSON的字符串之間轉(zhuǎn)換。

JSON進(jìn)階

Python的dict對(duì)象可以直接序列化為JSON的{},不過(guò),很多時(shí)候,我們更喜歡用class表示對(duì)象,比如定義Student類(lèi),然后序列化:

運(yùn)行代碼,毫不留情地得到一個(gè)TypeError

錯(cuò)誤的原因是Student對(duì)象不是一個(gè)可序列化為JSON的對(duì)象。

如果連class的實(shí)例對(duì)象都無(wú)法序列化為JSON,這肯定不合理!

別急,我們仔細(xì)看看dumps()方法的參數(shù)列表,可以發(fā)現(xiàn),除了第一個(gè)必須的obj參數(shù)外,dumps()方法還提供了一大堆的可選參數(shù):

https://docs.python.org/3/library/json.html#json.dumps

這些可選參數(shù)就是讓我們來(lái)定制JSON序列化。前面的代碼之所以無(wú)法把Student類(lèi)實(shí)例序列化為JSON,是因?yàn)槟J(rèn)情況下,dumps()方法不知道如何將Student實(shí)例變?yōu)橐粋€(gè)JSON的{}對(duì)象。

可選參數(shù)default就是把任意一個(gè)對(duì)象變成一個(gè)可序列為JSON的對(duì)象,我們只需要為Student專(zhuān)門(mén)寫(xiě)一個(gè)轉(zhuǎn)換函數(shù),再把函數(shù)傳進(jìn)去即可:

這樣,Student實(shí)例首先被student2dict()函數(shù)轉(zhuǎn)換成dict,然后再被順利序列化為JSON:

不過(guò),下次如果遇到一個(gè)Teacher類(lèi)的實(shí)例,照樣無(wú)法序列化為JSON。我們可以偷個(gè)懶,把任意class的實(shí)例變?yōu)?code>dict:

因?yàn)橥ǔ?code>class的實(shí)例都有一個(gè)__dict__屬性,它就是一個(gè)dict,用來(lái)存儲(chǔ)實(shí)例變量。也有少數(shù)例外,比如定義了__slots__的class。

同樣的道理,如果我們要把JSON反序列化為一個(gè)Student對(duì)象實(shí)例,loads()方法首先轉(zhuǎn)換出一個(gè)dict對(duì)象,然后,我們傳入的object_hook函數(shù)負(fù)責(zé)把dict轉(zhuǎn)換為Student實(shí)例:

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

打印出的是反序列化的Student實(shí)例對(duì)象。

小結(jié)

Python語(yǔ)言特定的序列化模塊是pickle,但如果要把序列化搞得更通用、更符合Web標(biāo)準(zhǔn),就可以使用json模塊。

json模塊的dumps()loads()函數(shù)是定義得非常好的接口的典范。當(dāng)我們使用時(shí),只需要傳入一個(gè)必須的參數(shù)。但是,當(dāng)默認(rèn)的序列化或反序列機(jī)制不滿足我們的要求時(shí),我們又可以傳入更多的參數(shù)來(lái)定制序列化或反序列化的規(guī)則,既做到了接口簡(jiǎn)單易用,又做到了充分的擴(kuò)展性和靈活性。



12.4 序列化的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
白玉县| 宜昌市| 忻州市| 土默特右旗| 阿克陶县| 塘沽区| 辉南县| 安徽省| 锡林浩特市| 泗水县| 大田县| 沐川县| 金堂县| 自治县| 清镇市| 佛山市| 乳山市| 锡林浩特市| 改则县| 昌都县| 盐源县| 枝江市| 双柏县| 桓台县| 栾川县| 潞城市| 彭山县| 鹰潭市| 樟树市| 南乐县| 旅游| 湘乡市| 高清| 宜昌市| 南川市| 八宿县| 高邮市| 大方县| 鄂托克旗| 洞头县| 肥乡县|