Python 物件序列化與反序列化:第 2 部分
這是關於序列化和反序列化 Python 物件的教程的第二部分。在第一部分中,您學習了基礎知識,然後深入研究了 Pickle 和 JSON 的細節。
在這一部分中,您將探索 YAML(確保擁有第一部分中的運行範例),討論效能和安全注意事項,了解其他序列化格式,最後了解如何選擇正確的方案。 p>
#YAML
YAML 是我最喜歡的格式。它是一種人性化的資料序列化格式。與 Pickle 和 JSON 不同,它不是 Python 標準庫的一部分,因此您需要安裝它:
pip 安裝 yaml
yaml模組只有load()
和dump()
函數。預設情況下,它們使用像loads()
和dumps()
這樣的字串,但可以採用第二個參數,它是一個開放流,然後可以轉儲/加載到/來自文件。
import yaml print yaml.dump(simple) boolean: true int_list: [1, 2, 3] none: null number: 3.44 text: string
請注意 YAML 與 Pickle 甚至 JSON 相比的可讀性。現在是 YAML 最酷的部分:它理解 Python 物件!無需自訂編碼器和解碼器。以下是使用 YAML 的複雜序列化/反序列化:
> serialized = yaml.dump(complex) > print serialized a: !!python/object:__main__.A simple: boolean: true int_list: [1, 2, 3] none: null number: 3.44 text: string when: 2016-03-07 00:00:00 > deserialized = yaml.load(serialized) > deserialized == complex True
如您所見,YAML 有自己的符號來標記 Python 物件。輸出仍然非常容易閱讀。日期時間物件不需要任何特殊標記,因為 YAML 本質上支援日期時間物件。
效能
在開始考慮效能之前,您需要考慮效能是否是一個問題。如果您相對不頻繁地序列化/反序列化少量資料(例如在程式開始時讀取設定檔),那麼效能並不是真正的問題,您可以繼續前進。
但是,假設您分析了系統並發現序列化和/或反序列化導致效能問題,則需要解決以下問題。
效能有兩個面向:序列化/反序列化的速度有多快,以及序列化表示有多大?
為了測試各種序列化格式的效能,我將建立一個較大的資料結構,並使用 Pickle、YAML 和 JSON 進行序列化/反序列化。 big_data
清單包含 5,000 個複雜物件。
big_data = [dict(a=simple, when=datetime.now().replace(microsecond=0)) for i in range(5000)]
泡菜
我將在這裡使用 IPython,因為它有方便的 %timeit
魔術函數來測量執行時間。
import cPickle as pickle In [190]: %timeit serialized = pickle.dumps(big_data) 10 loops, best of 3: 51 ms per loop In [191]: %timeit deserialized = pickle.loads(serialized) 10 loops, best of 3: 24.2 ms per loop In [192]: deserialized == big_data Out[192]: True In [193]: len(serialized) Out[193]: 747328
預設pickle需要83.1毫秒進行序列化,29.2毫秒進行反序列化,序列化大小為747,328位元組。
讓我們嘗試使用最高協定。
In [195]: %timeit serialized = pickle.dumps(big_data, protocol=pickle.HIGHEST_PROTOCOL) 10 loops, best of 3: 21.2 ms per loop In [196]: %timeit deserialized = pickle.loads(serialized) 10 loops, best of 3: 25.2 ms per loop In [197]: len(serialized) Out[197]: 394350
有趣的結果。序列化時間縮短至僅 21.2 毫秒,但反序列化時間略為增加,達 25.2 毫秒。序列化大小顯著縮小至 394,350 位元組 (52%)。
JSON
In [253] %timeit serialized = json.dumps(big_data, cls=CustomEncoder) 10 loops, best of 3: 34.7 ms per loop In [253] %timeit deserialized = json.loads(serialized, object_hook=decode_object) 10 loops, best of 3: 148 ms per loop In [255]: len(serialized) Out[255]: 730000
好的。編碼方面的表現似乎比 Pickle 差一點,但解碼的表現卻差很多很多:慢了 6 倍。這是怎麼回事?這是 object_hook
函數的一個工件,需要為每個字典執行以檢查是否需要將其轉換為物件。不使用物件掛鉤運行速度要快得多。
%timeit deserialized = json.loads(serialized) 10 loops, best of 3: 36.2 ms per loop
這裡的教訓是,在序列化和反序列化為 JSON 時,請仔細考慮任何自訂編碼,因為它們可能會對整體效能產生重大影響。
YAML
In [293]: %timeit serialized = yaml.dump(big_data) 1 loops, best of 3: 1.22 s per loop In[294]: %timeit deserialized = yaml.load(serialized) 1 loops, best of 3: 2.03 s per loop In [295]: len(serialized) Out[295]: 200091
好的。 YAML 真的非常非常慢。但是,請注意一些有趣的事情:序列化大小僅為 200,091 位元組。比 Pickle 和 JSON 都好得多。讓我們快速了解內部:
In [300]: print serialized[:211] - a: &id001 boolean: true int_list: [1, 2, 3] none: null number: 3.44 text: string when: 2016-03-13 00:11:44 - a: *id001 when: 2016-03-13 00:11:44 - a: *id001 when: 2016-03-13 00:11:44
YAML 在這裡非常聰明。它確定所有 5,000 個字典共享相同的“a”鍵值,因此它僅存儲一次並使用 *id001
為所有物件引用它。
安全性
安全性通常是一個關鍵問題。 Pickle和YAML由於建構Python對象,很容易受到程式碼執行攻擊。格式巧妙的檔案可以包含將由 Pickle 或 YAML 執行的任意程式碼。無需驚慌。這是設計使然,並記錄在 Pickle 的文檔中:
警告:pickle 模組並非旨在防止錯誤或惡意建構的資料。切勿取消從不受信任或未經身份驗證的來源收到的資料。
以及 YAML 文件中的內容:
警告:使用從不受信任的來源收到的任何資料呼叫 yaml.load 是不安全的! yaml.load 與 pickle.load 一樣強大,因此可以呼叫任何 Python 函數。
您只需要了解,不應使用 Pickle 或 YAML 載入從不受信任的來源收到的序列化資料。 JSON 沒問題,但是如果您有自訂編碼器/解碼器,那麼您也可能會暴露。
yaml 模組提供了 yaml.safe_load()
函數,該函數僅加載簡單的對象,但隨後您會失去很多 YAML 的功能,並且可能選擇只使用 JSON。
其他格式
還有許多其他可用的序列化格式。以下是其中的一些。
協定緩衝區
Protobuf(即協定緩衝區)是 Google 的資料交換格式。它是用 C 實現的,但具有 Python 綁定。它具有複雜的架構並有效地打包資料。非常強大,但不太容易使用。
訊息包
MessagePack 是另一種流行的序列化格式。它也是二進制且高效的,但與 Protobuf 不同的是它不需要模式。它有一個類似於 JSON 的類型系統,但更豐富一些。鍵可以是任何類型,不僅支援字串和非 UTF8 字串。
CBOR
CBOR 代表簡潔二進位物件表示。同樣,它支援 JSON 資料模型。 CBOR 不像 Protobuf 或 MessagePack 那麼出名,但它很有趣,原因有兩個:
- 它是官方網路標準:RFC 7049。
- 它是專為物聯網 (IoT) 設計。
如何選擇?
這是一個大問題。這麼多選擇,你如何選擇?讓我們考慮一下應該考慮的各種因素:
- 序列化格式應該是人類可讀和/或人類可編輯的嗎?
- 是否會從不受信任的來源接收序列化內容?
- 序列化/反序列化是效能瓶頸嗎?
- 序列化資料是否需要與非Python環境交換?
我會讓您變得非常簡單,並介紹幾種常見場景以及我為每種場景推薦的格式:
自動儲存Python程式的本機狀態
此處使用 pickle (cPickle) 和 HIGHEST_PROTOCOL
。它快速、高效,無需任何特殊程式碼即可儲存和載入大多數 Python 物件。它也可以用作本地持久緩存。
設定檔
絕對是 YAML。對於人類需要閱讀或編輯的任何內容來說,沒有什麼比它的簡單性更好的了。它已被 Ansible 和許多其他專案成功使用。在某些情況下,您可能會喜歡使用直接的 Python 模組作為設定檔。這可能是正確的選擇,但它不是序列化,它實際上是程式的一部分,而不是單獨的設定檔。
Web API
JSON 顯然是這裡的贏家。如今,Web API 最常由原生使用 JSON 的 JavaScript Web 應用程式使用。某些Web API 可能會傳回其他格式(例如,用於密集表格結果集的csv),但我認為您可以以最小的開銷將csv 資料打包為JSON(無需將每一行作為具有所有列名稱的物件重複)。
高容量/低延遲大規模通訊
使用二進位協定之一:Protobuf(如果需要架構)、MessagePack 或 CBOR。執行您自己的測試來驗證每個選項的效能和代表能力。
結論
Python物件的序列化和反序列化是分散式系統的一個重要面向。您無法直接透過網路傳送 Python 物件。您經常需要與其他語言實作的其他系統進行互通,有時您只想將程式的狀態儲存在持久性儲存中。
Python 在其標準庫中附帶了多種序列化方案,還有更多序列化方案可作為第三方模組使用。了解所有選項以及每個選項的優缺點將使您能夠選擇最適合您情況的方法。
以上是Python 物件序列化與反序列化:第 2 部分的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。Python以简洁和强大的生态系统著称,C 则以高性能和底层控制能力闻名。

2小時內可以學會Python的基本編程概念和技能。 1.學習變量和數據類型,2.掌握控制流(條件語句和循環),3.理解函數的定義和使用,4.通過簡單示例和代碼片段快速上手Python編程。

Python在遊戲和GUI開發中表現出色。 1)遊戲開發使用Pygame,提供繪圖、音頻等功能,適合創建2D遊戲。 2)GUI開發可選擇Tkinter或PyQt,Tkinter簡單易用,PyQt功能豐富,適合專業開發。

Python更易學且易用,C 則更強大但複雜。 1.Python語法簡潔,適合初學者,動態類型和自動內存管理使其易用,但可能導致運行時錯誤。 2.C 提供低級控制和高級特性,適合高性能應用,但學習門檻高,需手動管理內存和類型安全。

要在有限的時間內最大化學習Python的效率,可以使用Python的datetime、time和schedule模塊。 1.datetime模塊用於記錄和規劃學習時間。 2.time模塊幫助設置學習和休息時間。 3.schedule模塊自動化安排每週學習任務。

Python在開發效率上優於C ,但C 在執行性能上更高。 1.Python的簡潔語法和豐富庫提高開發效率。 2.C 的編譯型特性和硬件控制提升執行性能。選擇時需根據項目需求權衡開發速度與執行效率。

Python在自動化、腳本編寫和任務管理中表現出色。 1)自動化:通過標準庫如os、shutil實現文件備份。 2)腳本編寫:使用psutil庫監控系統資源。 3)任務管理:利用schedule庫調度任務。 Python的易用性和豐富庫支持使其在這些領域中成為首選工具。

pythonlistsarepartofthestAndArdLibrary,herilearRaysarenot.listsarebuilt-In,多功能,和Rused ForStoringCollections,而EasaraySaraySaraySaraysaraySaraySaraysaraySaraysarrayModuleandleandleandlesscommonlyusedDduetolimitedFunctionalityFunctionalityFunctionality。
