日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
更好的Python對(duì)象序列化方式

 許多Python標(biāo)準(zhǔn)庫(kù)都有一些未被賞識(shí)的精華。其中之一是允許簡(jiǎn)單優(yōu)雅的基于參數(shù)類型的函數(shù)分發(fā)。這一特性對(duì)于任意對(duì)象的序列化而言是非常完美的——例如對(duì)于web API的JSON或結(jié)構(gòu)化日志而言。

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供金壇網(wǎng)站建設(shè)、金壇做網(wǎng)站、金壇網(wǎng)站設(shè)計(jì)、金壇網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、金壇企業(yè)網(wǎng)站模板建站服務(wù),十余年金壇做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

 誰(shuí)應(yīng)該都見過(guò)這個(gè):

雖然這不是什么大問(wèn)題。json模塊(API繼承自simplejson)提供了兩種方式來(lái)序列化對(duì)象:

    1.   實(shí)現(xiàn)一個(gè)default()函數(shù),它接收一個(gè)對(duì)象作為參數(shù)并且返回可以被JSONEncoder理解的東西;

    2.   你自己實(shí)現(xiàn)或子類化一個(gè)JSONEncoder,并且把它作為cls傳遞給dump方法。你可以自己實(shí)現(xiàn)它或者簡(jiǎn)單地重寫JSONEncoder.default()方法。

由于一些第三方的實(shí)現(xiàn)希望能夠被大多數(shù)程序兼容,所以他們都不同程度的模仿了json模塊的API1。

擴(kuò)展性

所有上述方法的共性是它們不具有擴(kuò)展性:不提供對(duì)新類型的支持。你的default()函數(shù)需要知道所有你想要序列化的自定義類型。這意味著你或者像這樣寫你的函數(shù):

這看起來(lái)非常痛苦,因?yàn)槟阈枰谝粋€(gè)地方為所有不同類型對(duì)象增加序列化結(jié)果2。

或者另一種方法,你可以自己嘗試提出一種一般性的解決方案,就像Pyramid的JSON渲染器在JSON.add_adapter中做的一樣,它使用了被廣泛低估的zope.interface的適配器注冊(cè)表3。

另一方面,Django自己實(shí)現(xiàn)了一個(gè)DjangoJSONEncoder,它是json.JSONEncoder的子類,它知道如何去編碼日期,時(shí)間,UUID和premise等。但是除此之外,你又需要依靠自己了。如果你想深入研究Django和web API,那么你可能已經(jīng)準(zhǔn)備好使用Django的REST框架了。它們實(shí)現(xiàn)了一整套序列化系統(tǒng),它比僅僅讓數(shù)據(jù)進(jìn)行json.dump()做了更多的工作。

最后,為了完整性,我感覺(jué)我不得不提到我自己在我第一天開始就極其討厭的structlog中的解決方案:為你的類增加一個(gè)__structlog__方法,它會(huì)像__str__一樣返回一個(gè)序列化后的表示方法。請(qǐng)不要重復(fù)我的錯(cuò)誤。標(biāo)簽:software clown。

JSON已經(jīng)很流行了,然而很奇怪的是我們對(duì)于序列化的解決方案卻仍舊不夠完善。我個(gè)人想要的是能夠注冊(cè)一個(gè)中心化的序列化工具,但是卻以一個(gè)去中心化的方式來(lái)使用,這樣可以不需要對(duì)我的類(或者更糟的,第三方類)進(jìn)行任何修改。

進(jìn)入PEP443

Python3.4以PEP 443的形式給出了對(duì)這個(gè)問(wèn)題的一個(gè)好的解決方案:functools.singledispatch(老式Python版本也可以在PyPI上找到)。

簡(jiǎn)單說(shuō),你可以定義一個(gè)默認(rèn)的函數(shù)然后根據(jù)第一個(gè)參數(shù)的類型注冊(cè)一個(gè)該函數(shù)的額外版本:

現(xiàn)在你也可以對(duì)datetime實(shí)例調(diào)用to_serializable()方法,singledispatch會(huì)選擇正確的函數(shù)。

這一方法讓你能夠把你的序列化器放在任何你想放的位置:放在類里,在一個(gè)獨(dú)立的模塊里,或者放在JSON相關(guān)的代碼里。你自己選!但是你的類要保持干凈,并且你不需要巨大的繁瑣的if-elif-else分支。

更深入一點(diǎn)

顯然,@singledispatch的使用比JSON更加深入。一般而言,為不同類型的對(duì)象綁定不同的行為以及獨(dú)立的序列化方式是普遍適用的4。我的一些校對(duì)員提到了他們嘗試了采用字典類近似替代可調(diào)用對(duì)象以及其他一些類似的“殘暴的”做法。

換句話說(shuō),@singledispatch就是一個(gè)長(zhǎng)久以來(lái)就存在的但是卻被你忽略的函數(shù)。

P.S. 當(dāng)然,PyPI中也有一個(gè)*multiple*dispatch。

腳注

1.   然而,對(duì)于非常出名的一個(gè):UltraJSON一點(diǎn)都不支持自定義對(duì)象的序列化,此外,python-rapidjson僅僅支持default()函數(shù)。

2.   利用attrs是可以很好管理的!也許你應(yīng)當(dāng)使用attrs!

3.   不幸的是Pyramid使用的API自從zope.component移植過(guò)來(lái)之后還沒(méi)有形成文檔。

4.   我聽說(shuō)將singlepatch加進(jìn)標(biāo)準(zhǔn)庫(kù)的最原始動(dòng)力來(lái)自于對(duì)pprint的一個(gè)更優(yōu)雅的實(shí)現(xiàn)(雖然從來(lái)沒(méi)有實(shí)現(xiàn)過(guò))


當(dāng)前標(biāo)題:更好的Python對(duì)象序列化方式
URL標(biāo)題:http://m.5511xx.com/article/cdpeoid.html