これは、Python オブジェクトのシリアル化と逆シリアル化に関するチュートリアルの 2 番目の部分です。最初のパートでは、基本を学び、次に Pickle と JSON の詳細を掘り下げました。
このパートでは、YAML について学び (パート 1 の実行例を必ず入手してください)、パフォーマンスとセキュリティに関する考慮事項について説明し、他のシリアル化形式について学び、最後に適切なシリアル化形式を選択する方法を学びます。 p>
YAML は私のお気に入りの形式です。これは人間にとって使いやすいデータシリアル化形式です。 Pickle や JSON とは異なり、Python 標準ライブラリの一部ではないため、インストールする必要があります:
pip インストール yaml
yaml モジュールには、load()
関数と dump()
関数のみがあります。デフォルトでは、loads()
や dumps()
のような文字列を受け取りますが、オープン ストリームである 2 番目の引数を受け取り、ファイルにダンプ/ロードしたり、ファイルからロードしたりすることもできます。
Pickle や JSON と比較して、YAML がどれほど読みやすいかに注目してください。ここからが YAML のすごいところです。YAML は Python オブジェクトを理解します。カスタムのエンコーダやデコーダは必要ありません。 YAML を使用した複雑なシリアル化/逆シリアル化は次のとおりです:
リーリーご覧のとおり、YAML には Python オブジェクトをマークするための独自の表記法があります。出力は依然として非常に読みやすいです。 YAML は本質的に日時オブジェクトをサポートしているため、日時オブジェクトには特別なマークアップは必要ありません。
###パフォーマンス###ただし、システムのプロファイリングを行って、シリアル化および/または逆シリアル化がパフォーマンスの問題を引き起こしていることが判明した場合は、次の問題に対処する必要があります。
パフォーマンスには 2 つの側面があります。シリアル化/逆シリアル化の速度と、シリアル化された表現の大きさです。
さまざまなシリアル化形式のパフォーマンスをテストするために、より大きなデータ構造を作成し、Pickle、YAML、および JSON を使用してシリアル化/逆シリアル化します。
big_data リストには 5,000 個の複雑なオブジェクトが含まれています。
リーリー
ピクルス
マジック関数があるため、ここでは IPython を使用します。
リーリー
デフォルトの pickle は、シリアル化に 83.1 ミリ秒、逆シリアル化に 29.2 ミリ秒かかり、シリアル化のサイズは 747,328 バイトです。
最上位のプロトコルを使用してみましょう。
リーリー興味深い結果です。シリアル化時間はわずか 21.2 ミリ秒に減少しましたが、逆シリアル化時間は 25.2 ミリ秒にわずかに増加しました。シリアル化されたサイズは 394,350 バイト (52%) に大幅に減少します。
JSON
リーリー ###わかりました。エンコードのパフォーマンスは Pickle よりも少し悪いように見えますが、デコードのパフォーマンスははるかに悪く、6 倍も遅くなります。これはどうなっているでしょうか?これは
リーリー
ここでの教訓は、JSON へのシリアル化および逆シリアル化の際にカスタム エンコーディングを慎重に検討することです。カスタム エンコーディングは全体的なパフォーマンスに大きな影響を与える可能性があります。
リーリー ###わかりました。 YAML は本当に遅いです。ただし、興味深いことに注意してください。シリアル化されたサイズはわずか 200,091 バイトです。 Pickle と JSON の両方よりもはるかに優れています。内部を簡単に見てみましょう:
リーリーを使用して参照します。
###安全性### セキュリティは多くの場合重要な問題です。 Pickle と YAML は、Python オブジェクトの構築によりコード実行攻撃に対して脆弱です。適切にフォーマットされたファイルには、Pickle または YAML によって実行される任意のコードが含まれる可能性があります。パニックになる必要はありません。これは仕様であり、Pickle のドキュメントに記載されています:
警告: pickle モジュールは、誤ったデータや悪意を持って構築されたデータから保護するように設計されていません。信頼できないソースまたは認証されていないソースから受信したデータは決してキャンセルしないでください。
警告: 信頼できないソースから受信したデータを使用して 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 は、Concise Binary Object Representation の略です。同様に、JSON データ モデルをサポートします。 CBOR は Protobuf や MessagePack ほど有名ではありませんが、次の 2 つの理由で興味深いものです。
Python プログラムのローカル状態を自動的に保存する
HIGHEST_PROTOCOL を使用します。高速かつ効率的で、特別なコードを必要とせずにほとんどの Python オブジェクトを保存およびロードできます。ローカル永続キャッシュとしても使用できます。
ウェブ API
大容量・低遅延の大規模通信
###結論は###
Python オブジェクトのシリアル化と逆シリアル化は、分散システムの重要な側面です。 Python オブジェクトをネットワーク経由で直接送信することはできません。多くの場合、他の言語で実装された他のシステムと相互運用する必要があり、プログラムの状態を永続ストレージに保存したい場合もあります。以上がPython オブジェクトのシリアル化と逆シリアル化: パート 2の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。