シリアル化とは、オブジェクトをバイトストリーム(または文字列)に変換するプロセスであり、保存またはネットワーク越しに送信するためです。デシリアル化はその逆の操作です。
歴史的に、Pythonにおける主な問題は、さまざまなアプリケーションや言語間で複雑なデータ構造の交換を標準化することでした。このため、標準ライブラリにはさまざまなモジュールが登場しました。最初はpickleがあり、Pythonオブジェクトのシリアル化のために使用され、後に外部システムとのユニバーサルな交換のためのjsonが登場しました。
問題:pickleはPython特有のデータを保持し、安全ではありません(読み込み時に任意のコードを実行する可能性があります)し、他の言語と互換性がありません。一方、jsonは基本的な型(dict、list、str、int、float、bool、None)のみに制限されますが、安全であり、異なる技術間での交換に広く使用されます。
解決策:pickleはPythonシステム間で信頼できるデータのみに使用し、jsonは外部サービスとの交換、ウェブ開発、可読性のあるデータの構造の伝達に使用します。
コード例:
import pickle import json data = {'a': [1, 2, 3], 'b': True} # pickleによるシリアル化 pickled = pickle.dumps(data) # バイト unpickled = pickle.loads(pickled) print(unpickled) # jsonによるシリアル化 jsoned = json.dumps(data) # 文字列 unjsoned = json.loads(jsoned) print(unjsoned)
主な特徴:
pickleを介して外部システムにHTTP APIの応答を送信することは可能ですか?
いいえ!pickleは言語間のデータ交換の標準ではなく、非常に安全ではありません:pickleからの読み込みは外部のコードを実行することがあります。jsonは外部との相互作用においてはるかに優れています。
関数、クラス、またはラムダ関数をjsonでシリアル化することはできますか?
いいえ。jsonはプリミティブ型のみで動作し、関数やクラスは標準のjsonやほとんどのパーサーではシリアル化できません。
pickleは循環参照を持つオブジェクトをシリアル化できますか?
はい、pickleはほとんどの循環参照を自動的に処理し、再帰的な構造にまで対応します。jsonでは通常、致命的なエラーになります。
ネガティブケース:クライアントアプリケーションにデータを交換するためのpickleオブジェクトを渡す。
利点:実装が簡単で、すべてのPython型を保持します。
欠点:極めて危険で、他の言語との相互作用が不可能です。
ポジティブケース:jsonを介したデータ送信、カスタムエンコーダーを使用して非標準型を変換します。
利点:安全性、互換性、柔軟性。
欠点:サポートされる型の制限があり、時々カスタムエンコーダー/デコーダーを必要とします。