文字列のシーケンス化と逆シーケンス化

15357 ワード

前節では、ファイルの読み書きを学び、文字列(またはバイトオブジェクト)をディスクに保存するのは簡単です.しかし、実際のプログラミングでは、複雑な辞書やネストされたリストなどの構造化データを保存する必要があります.この場合、これらの構造化データをまず文字列に変換する方法が必要です.この変換プロセスを「シーケンス化」と呼び、このプロセスの逆操作は「逆シーケンス化」です.
JSONシーケンス化
シーケンス化されたデータの操作は、各言語のプログラミングで発生します.もちろん、JSON(JavaScript Object Notation)などの標準化されたフォーマットもあります.JSONフォーマットは通常、現代のアプリケーションでデータ交換に用いられ、特にWebで広く知られており、多くのプログラマーの選択である.PythonがJSONをサポートするモジュールをjsonといいます.
JSONのデータフォーマットはPythonの辞書とリストとよく似ており、辞書とリストが互いにネストされた結合体と言えるが、これらの辞書とリストの基本データ型は文字列、整数、浮動小数点数、ブール型、None、カスタムクラスなどの複雑なオブジェクトではない.
1つのオブジェクトxは、1行の簡単なコードで対応するJSON文字列に変換できます.
In [124]: import json

In [125]: json.dumps({
     'Tom': 23, 'Jim': 25, 'William': 21})
Out[125]: '{"Tom": 23, "Jim": 25, "William": 21}'

JSON文字列をPythonオブジェクトに逆シーケンス化するコードも1行しかありません.
In [126]: json.loads('{"Tom": 23, "Jim": 25, "William": 21}')
Out[126]: {
     'Tom': 23, 'Jim': 25, 'William': 21}

dumps()メソッドにはdump()という変形があり、オブジェクトをファイルにシーケンス化します.fがファイルオブジェクトである場合、私たちはこのように操作することができます.json.dump(x, f)
これに対応して、ファイルオブジェクトfから逆シーケンス化する操作は、x = json.load(f)
dumps()関数には多くのパラメータがオプションであり、異なるフォーマットのJSON文字列を生成することができ、具体的にはIPythonでjsonを通過することができる.dumps?に表示されます.(1)コンパクト符号化はseparatorsパラメータによって実現される.
In [130]: json.dumps({
     "Tom": 23, "Jim": 25, "William": 21}, separators=(',', ':'))
Out[130]: '{"Tom":23,"Jim":25,"William":21}'

(2)美化出力はsort_keys,indentパラメータで実現する:
In [132]: print(json.dumps({
     "Tom": 23, "Jim": 25, '9':3, '3': 10}, sort_keys=True, indent=4))
{
     
    "3": 10,
    "9": 3,
    "Jim": 25,
    "Tom": 23
}

(3)中国語符号化パラメータensure_asciiのデフォルトはTrueで、中国語などの非ascii文字が変換されます.
In [133]: print(json.dumps({
     "  ": 23, "  ": 25, '9':3, '3': 10}, sort_keys=True, indent=4))
{
     
    "3": 10,
    "9": 3,
    "\u5c0f\u521a": 23,
    "\u5c0f\u660e": 25
}

In [134]: print(json.dumps({
     "  ": 23, "  ": 25, '9':3, '3': 10}, sort_keys=True, indent=4, ensure_ascii=False))
{
     
    "3": 10,
    "9": 3,
    "  ": 23,
    "  ": 25
    }

pickleモジュールシーケンス化
jsonモジュールとは異なり、pickleは任意の複雑なPythonオブジェクトをシーケンス化することができ、Python特有であり、他の言語と通信できない.デフォルトでは、データがハッカーによって丹念に設計されている場合、逆シーケンス化されたデータに悪意のあるコードが埋め込まれる可能性があります.
pickleのインタフェースはjsonと同様で,シーケンス化はdumps(x),dump(x,f),逆シーケンス化はloads(s),load(f)を用いる.しかし、pickleは、カスタムクラスや関数など、任意の複雑なオブジェクトをシーケンス化することができます.たとえば、次の例は、bをシーケンス化し、関数を逆シーケンス化する例です.
In [136]: def add(x, y): 
     ...:     print(x+y) 
     ...:

In [137]: import pickle

In [138]: s = pickle.dumps(add)

In [139]: s
Out[139]: b'\x80\x03c__main__
add
q\x00.'
In [140]: f = pickle.loads(s) In [141]: f Out[141]: <function __main__.add(x, y)> In [142]: f(2, 3) 5

この例から,1つの関数をシーケンス化し逆シーケンス化する機能を実現した.このように、いくつかの関数、カスタムクラスなどのさまざまなオブジェクトを先にファイルにシーケンス化し、このファイルを他の人に送ることができます.他の人は逆シーケンス化でこれらのカスタムクラスと関数を使用することができます.この過程で,ファイルを修正して関数add()の実装を修正するなど,シーケンス化ファイルに手を加える人がいれば,ハッカーに攻撃に利用される可能性がある.これも前にpickleのデフォルトが安全ではないと言った理由です.だから、それを用いてシーケンス化するかどうかを選ぶときは、まず考えてみましょう.
まとめ
Pythonはデータシーケンス化のツールを提供してくれました.他のプログラムとデータ交換が必要な場合は、jsonが最善の選択です.自分の内部で使用する場合、pickleは選択として複雑なオブジェクトのシーケンス化を行うことができます.転入先