全方位盤點(diǎn)Python 中 6 款 JSON 庫,不容錯(cuò)過形葬!

REST API 是 在全世界使用標(biāo)準(zhǔn)化的消息格式合呐。JSON 是互聯(lián)網(wǎng)上數(shù)據(jù)交換的基石,作為 JavaScript 的一個(gè)子集笙以,它從一開始就獲得了巨大的推廣淌实。它特別清晰易讀的語法也有利于推廣。

據(jù)我所知各種語言都有 JSON 庫用于序列化和反序列化猖腕。實(shí)際上在 Python 中就有很多種 JSON 庫拆祈。在下文中,我將為大家比較它們的異同倘感。

引用庫

CPython 本身具有一個(gè) json 模塊放坏。它最初是由 Bob Ippolito 作為 simplejson 開發(fā)的,并被合并到 Python 2.4 中(源代碼)老玛。CPython 遵循 Python 軟件基金會(huì)(Python Software Foundation)許可協(xié)議淤年。

simplejson 仍然作為一個(gè)單獨(dú)的庫存在钧敞,你可以通過 pip 安裝它。它是帶有可選 C 擴(kuò)展的純 Python 庫互亮。Simplejson 遵循 MIT 和 Academic Free License(AFL)許可協(xié)議犁享。

ujson 是對(duì) C 語言庫 Ultra JSON 的綁定。Ultra JSON 由 ESN(一家電子藝術(shù)工作室公司)開發(fā)豹休,并獲得了 3條款BSD許可炊昆。Ultra JSON 在 Github 上擁有 3k 星,305 個(gè) fork威根,50 個(gè)貢獻(xiàn)者凤巨,最近一次提交的日期只有 12 天,而最后一次提交是在 5 天之前發(fā)布的洛搀。我聽說它處于“維護(hù)模式”(來源)敢茁,表明沒有新的進(jìn)展。

pysimdjson 是對(duì) C ++ 庫 simdjson 的綁定留美。SIMDjson 從加拿大獲得資助彰檬。simdjson 在 Github 上有 12.2k 顆星,611 個(gè)分支谎砾,63 個(gè)貢獻(xiàn)者逢倍,最后一次提交是 11 小時(shí)前,而最后一個(gè) issue 是 2 小時(shí)前創(chuàng)建的景图。

python-rapidjson 是對(duì) C ++ 庫 RapidJSON 的綁定较雕。RapidJSON 由 騰訊 開發(fā)。RapidJSON 在 GitHub 上有 9.8k 個(gè)星挚币,2.7k 個(gè) fork亮蒋,150 個(gè)貢獻(xiàn)者,最近一次提交大約在 2 個(gè)月前妆毕,而最后一個(gè) issue 是 17 天前創(chuàng)建的慎玖。

orjson 是一個(gè) Python 軟件包,依靠 Rust 來完成繁重的工作设塔。

成熟度和操作安全性

上面所有提到的庫都可以毫無問題地用作 benchmark 示例凄吏,切換 JSON 模塊也不是什么大問題,但我仍然想確定相關(guān)模塊是否支持闰蛔。

CPython痕钢,simplejson,ujson 和 orjson 都認(rèn)為他們自己已經(jīng)可以投產(chǎn)了序六。

python-rapidjson 將自身標(biāo)記為 alpha任连,但是一位維護(hù)人員說這是一個(gè)錯(cuò)誤,并將很快得到修復(fù)(資源)例诀。

1.jpg

問題

判斷一個(gè)庫的問題是否能夠被順利解決随抠,一個(gè)直接的方式是直接去它的倉(cāng)庫創(chuàng)建 issue裁着,并觀察后續(xù)的跟進(jìn)反饋:

  • SimpleJSON:第二天我得到了答復(fù),回答很明確拱她,易于理解二驰,友善。Bob Ippolito 回答了我秉沼。他是最初開發(fā)這個(gè)庫的人桶雀,并且在 JSON 模塊的 Python 文檔中也提到了他!

  • uJSON:30分鐘內(nèi)唬复,我得到了一個(gè)清晰矗积,友好,易于遵循的答案敞咧。@hugovank

  • ORJSON:10天沒有反應(yīng)棘捣,然后關(guān)閉,沒有任何評(píng)論休建。

  • [PySIMDJSON]:15天后無人答復(fù)乍恐。

  • Python-RapidJSON:在30分鐘內(nèi),我得到了一個(gè)清晰测砂,友好禁熏,易于遵循的答案。十天后合并了一個(gè)簡(jiǎn)單的PR邑彪。

通過以上操作我得出一個(gè)答案,它們基本上沒有相互關(guān)系胧华。

基準(zhǔn)測(cè)試(Benchmark)

為了正確地對(duì)不同的庫進(jìn)行基準(zhǔn)測(cè)試寄症,我考慮了以下情況:

  • API:交換信息的 Web 服務(wù)。它可能包含 Unicode 并具有嵌套結(jié)構(gòu)矩动。Twitter API 的 JSON 文件聽起來不錯(cuò)有巧,可以對(duì)此進(jìn)行測(cè)試。

  • API JSON錯(cuò)誤:我很好奇如果 JSON API 格式有錯(cuò)誤悲没,性能會(huì)如何變化篮迎。因此,我在中間刪除了一個(gè)大括號(hào)示姿。

  • GeoJSON:我首先通過一個(gè)開源街道地圖導(dǎo)出器 Overpass Turbo 得到了 GeoJSON 格式的 JSON 文件甜橱。你將獲得瘋狂多的 JSON 文件,這些文件大多具有坐標(biāo)栈戳,而且還很嵌套岂傲。

  • 機(jī)器學(xué)習(xí):只是大量的浮點(diǎn)數(shù)列表。這些可能是神經(jīng)網(wǎng)絡(luò)層的權(quán)重子檀。

  • JSON行:結(jié)構(gòu)化日志在行業(yè)中大量使用镊掖。如果分析這些日志乃戈,可能需要遍歷千兆字節(jié)的數(shù)據(jù)。它們都是帶有日期時(shí)間對(duì)象亩进、消息症虑、記錄器、日志狀態(tài)等信息的簡(jiǎn)單字集归薛。

反序列化速度

我將我的硬盤驅(qū)動(dòng)器的讀取速度設(shè)置了一個(gè)較低的上限谍憔,在以下3個(gè)圖表中將以它作為基準(zhǔn)。

2.jpg

3.jpg

4.jpg

5.jpg

6.jpg

由此得出的結(jié)論是:

  • Rapidjson 速度很慢苟翻,但是對(duì)于像 twitter.json 這樣的小型 JSON韵卤,你不會(huì)注意到有什么不同〕缑ǎ可以通過結(jié)構(gòu)化日志看到這一點(diǎn)沈条。

  • simdjson,orjson 和 ujson 都快得驚人诅炉。

  • 對(duì)于大多數(shù)庫而言蜡歹,讀取包含結(jié)構(gòu)錯(cuò)誤的 JSON 文件的速度相同。一個(gè)值得注意的例外是 Rapidjson涕烧。我猜一旦發(fā)現(xiàn)錯(cuò)誤月而,它將中止讀取文件。

序列化速度

在這里议纯,我預(yù)先創(chuàng)建了 JSON 字符串,并以寫入磁盤的時(shí)間作為基線測(cè)量了所需的時(shí)間父款。


7.jpg

8.jpg

9.jpg

10.jpg

我由此得出的結(jié)論是:

  • orjson 非常快瞻凤,超級(jí)接近我的硬盤驅(qū)動(dòng)器寫入速度憨攒。ujson 也非常接近。

  • Rapidjson 也很快阀参,但與 orjson 或 ujson 不在同一級(jí)別肝集。

  • simdjson 很慢。

專業(yè)的 JSON 工作流

最后總結(jié)一下蛛壳,我想指出一些我之前看到并記錄下來的問題:

  • 調(diào)用變量 foo_json:JSON 是一種字符串格式杏瞻。如果不是字符串,則不是 JSON衙荐。如果使用 bar = json.loads(foo) 反序列化 JSON捞挥,則 bar 不是 JSON。

    你可以將 bar 序列化為與 JSON foo 等效的 JSON忧吟,但 bar 不是 JSON,這是一個(gè) Python 對(duì)象树肃,很像一個(gè)字典對(duì)象,就將它當(dāng)作 foo_json瀑罗。

  • 屬性會(huì)在各處進(jìn)行檢查:如果你收到 JSON 數(shù)據(jù)胸嘴,很輕松就可以轉(zhuǎn)換為 Python 對(duì)象(例如字典)并使用它雏掠。這對(duì)于概念驗(yàn)證代碼或很小的 JSON 字符串來說是很好的選擇。如果你不將其轉(zhuǎn)換為 dataclass 之類的劣像,它將一團(tuán)糟乡话。

pydantic 是一個(gè)超級(jí)有用的驗(yàn)證庫。你可以使用自己喜歡的 JSON 庫將 JSON 字符串解析為帶有 字典/列表/字符串/數(shù)字/布爾值的 Python 基本表示形式耳奕,然后再使用 Pydantic 對(duì)其進(jìn)行解析绑青。這樣做的好處是你知道以后要處理的內(nèi)容。不再只是將 Dict[str, Any] 用作 type annotation,不再用沒用的的編輯器自動(dòng)完成屋群,不再檢查屬性是否在整個(gè)代碼中都存在闸婴。

要引入除默認(rèn) json 以外的其他 json 包,我建議使用此模式

image.png

對(duì)于 Flask芍躏,你可以使用其他 編碼器/解碼器邪乍,如下所示:

image.png

今天的內(nèi)容就到這里啦,希望這篇文章對(duì)你有所幫助对竣,喜歡不要忘記收藏庇楞、轉(zhuǎn)發(fā)、評(píng)論否纬,點(diǎn)點(diǎn)關(guān)注哦吕晌!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市临燃,隨后出現(xiàn)的幾起案子睛驳,更是在濱河造成了極大的恐慌,老刑警劉巖膜廊,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柏靶,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡溃论,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門痘昌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钥勋,“玉大人,你說我怎么就攤上這事辆苔∷憔模” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵驻啤,是天一觀的道長(zhǎng)菲驴。 經(jīng)常有香客問我,道長(zhǎng)骑冗,這世上最難降的妖魔是什么赊瞬? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任先煎,我火速辦了婚禮,結(jié)果婚禮上巧涧,老公的妹妹穿的比我還像新娘薯蝎。我一直安慰自己,他們只是感情好谤绳,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布占锯。 她就那樣靜靜地躺著,像睡著了一般缩筛。 火紅的嫁衣襯著肌膚如雪消略。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天瞎抛,我揣著相機(jī)與錄音艺演,去河邊找鬼。 笑死婿失,一個(gè)胖子當(dāng)著我的面吹牛钞艇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播豪硅,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼哩照,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了懒浮?” 一聲冷哼從身側(cè)響起飘弧,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎砚著,沒想到半個(gè)月后次伶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡稽穆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年冠王,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舌镶。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡柱彻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出餐胀,到底是詐尸還是另有隱情哟楷,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布否灾,位于F島的核電站卖擅,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惩阶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一挎狸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧琳猫,春花似錦伟叛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至账千,卻和暖如春侥蒙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背匀奏。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工鞭衩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人娃善。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓论衍,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親聚磺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子坯台,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容