這是關於序列化和反序列化 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中文網其他相關文章!

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

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

Python在web開發、數據科學、機器學習、自動化和腳本編寫等領域有廣泛應用。 1)在web開發中,Django和Flask框架簡化了開發過程。 2)數據科學和機器學習領域,NumPy、Pandas、Scikit-learn和TensorFlow庫提供了強大支持。 3)自動化和腳本編寫方面,Python適用於自動化測試和系統管理等任務。

兩小時內可以學到Python的基礎知識。 1.學習變量和數據類型,2.掌握控制結構如if語句和循環,3.了解函數的定義和使用。這些將幫助你開始編寫簡單的Python程序。

如何在10小時內教計算機小白編程基礎?如果你只有10個小時來教計算機小白一些編程知識,你會選擇教些什麼�...

使用FiddlerEverywhere進行中間人讀取時如何避免被檢測到當你使用FiddlerEverywhere...

Python3.6環境下加載Pickle文件報錯:ModuleNotFoundError:Nomodulenamed...

如何解決jieba分詞在景區評論分析中的問題?當我們在進行景區評論分析時,往往會使用jieba分詞工具來處理文�...


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

WebStorm Mac版
好用的JavaScript開發工具

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。