Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonオブジェクトのシリアル化(Pickle)徹底解説|pickleモジュールの基本と使い方

オブジェクトのシリアル化とは

オブジェクトのシリアル化(serialization)とは、オブジェクトの状態をバイトストリーム(バイト列)に変換するプロセスを指します。一度生成されたバイトストリームは、ファイルに保存したり、ソケット経由で送信したりすることができます。逆に、バイトストリームから元のオブジェクトを復元する処理はデシリアル化(deserialization)と呼ばれます。

Pythonでは、シリアル化のことを「ピクル化(pickling)」、デシリアル化のことを「アンピクル化(unpickling)」と呼びます。標準ライブラリに含まれるpickleモジュールは、シリアル化用の関数 dump() / dumps()、およびデシリアル化用の関数 load() / loads() を提供しています。

ただし、pickleモジュールはPython固有のデータ形式を使用するため、Python以外の言語で書かれたプログラムでは、ピクル化されたデータを正しく復元できない場合があります。また、信頼できない(認証されていない)ソースからのデータをアンピクル化することはセキュリティ上のリスクとなるため、注意が必要です。

pickleプロトコルの種類

プロトコルとは、Pythonオブジェクトをバイナリデータへ変換・復元する際に用いられる規約のことです。現在、pickleモジュールでは以下の5種類のプロトコルが定義されています。

プロトコル バージョン0当初の「人間が読める」テキスト形式のプロトコル。以前のバージョンとの後方互換性があります。
プロトコル バージョン1旧バイナリ形式。こちらも以前のバージョンのPythonと互換性があります。
プロトコル バージョン2Python 2.3で導入。新スタイルクラスを効率的にピクル化できます。
プロトコル バージョン3Python 3.0で追加。他のPython 3系バージョンとの互換性が必要な場合に推奨されます。
プロトコル バージョン4Python 3.4で追加。非常に大きなオブジェクトのサポートが加わりました。

なお、Python 3.8以降では帯域外(out-of-band)データバッファに対応したプロトコル バージョン5も利用可能です。

自身のPython環境における最高プロトコルバージョンとデフォルトプロトコルバージョンは、pickleモジュールで定義されている次の定数で確認できます。

>>> import pickle
>>> pickle.HIGHEST_PROTOCOL
4
>>> pickle.DEFAULT_PROTOCOL
3

dump() と load() によるファイルへの保存・復元

pickleモジュールの dump() 関数と load() 関数は、それぞれPythonデータのピクル化とアンピクル化を行います。dump() はピクル化したオブジェクトをファイルに書き込み、load() はファイルからデータを読み込んでPythonオブジェクトとして復元します。

次のプログラムは、辞書オブジェクトをバイナリファイルにピクル化する例です。

import pickle
f = open("data.txt","wb")
dct = {"name":"Ravi", "age":23, "Gender":"M", "marks":75}
pickle.dump(dct, f)
f.close()

このコードを実行すると、辞書オブジェクトのバイト表現が data.txt ファイルに保存されます。

バイナリファイルからデータをアンピクル化し、元の辞書に戻すには次のようにします。

import pickle
f = open("data.txt","rb")
d = pickle.load(f)
print(d)
f.close()

Pythonコンソールには、ファイルから読み込んだ辞書オブジェクトが表示されます。

{'age': 23, 'Gender': 'M', 'name': 'Ravi', 'marks': 75}

dumps() と loads() による文字列への変換

pickleモジュールには、ピクル化したデータの文字列表現(bytesオブジェクト)を返す dumps() 関数も用意されています。

>>> from pickle import dumps
>>> dct = {"name":"Ravi", "age":23, "Gender":"M", "marks":75}
>>> dctstring = dumps(dct)
>>> dctstring
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x04\x00\x00\x00Raviq\x02X\x03\x00\x00\x00ageq\x03K\x17X\x06\x00\x00\x00Genderq\x04X\x01\x00\x00\x00Mq\x05X\x05\x00\x00\x00marksq\x06KKu.'

loads() 関数を使えば、この文字列をアンピクル化して元の辞書オブジェクトを取得できます。

>>> from pickle import loads
>>> dct = loads(dctstring)
>>> dct
{'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75}

PicklerクラスとUnpicklerクラス

pickleモジュールには、Pickler クラスと Unpickler クラスも定義されています。Picklerクラスはピクルデータをファイルに書き込み、Unpicklerクラスはファイルからバイナリデータを読み込んでPythonオブジェクトを構築します。

Pythonオブジェクトのピクルデータを書き込む例:

from pickle import Pickler
f = open("data.txt","wb")
dct = {'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75}
Pickler(f).dump(dct)
f.close()

バイナリファイルをアンピクル化してデータを読み戻す例:

from pickle import Unpickler
f = open("data.txt","rb")
dct = Unpickler(f).load()
print(dct)
f.close()

カスタムクラスのオブジェクトをピクル化する

Python標準のすべてのデータ型のオブジェクトはピクル化可能です。さらに、ユーザー定義クラスのインスタンスもピクル化・アンピクル化できます。

from pickle import *

class person:
def __init__(self):
self.name = "XYZ"
self.age = 22
def show(self):
print("name:", self.name, "age:", self.age)

p1 = person()
f = open("data.txt","wb")
dump(p1, f)
f.close()

print("unpickled")
f = open("data.txt","rb")
p1 = load(f)
p1.show()

まとめ

このように、pickleモジュールを使えばPythonオブジェクトを簡単にファイルへ保存し、後から元の状態で復元できます。なお、PythonライブラリにはPythonオブジェクトの内部シリアル化に用いられる marshal モジュールも存在しますが、marshalは主にインタプリタ内部(.pycファイルの読み書きなど)向けのものであり、一般的なデータの永続化にはpickleモジュールの利用が推奨されています。

  1. Pythonで身につける統計的思考 ― グラフとチャートによるデータ分析入門

    統計学は、機械学習(ML)やAIを学ぶうえで欠かせない基礎知識です。これらの技術分野ではPythonが事実上の標準言語となっているため、統計分析を取り入れたPythonプログラムの書き方をマスターすることが重要になります。本記事では、さまざまなPythonライブラリを活用してグラフやチャートを作成する方法を解説します。多様なチャートを使いこなせるようになると、データを素早く分析し、結論を視覚的に導き出せるようになります。 データの準備 ここでは、さまざまな種子(シード)に関するデータを含むデータセットを使用します。このデータセットはKaggleから入手でき、URLは後述のサンプルコード内に記載

  2. Pythonで国勢調査データを分析する方法|インドの人口統計データを可視化してみよう

    国勢調査(センサス)とは、特定の対象人口に関する情報を体系的に記録・収集する取り組みです。収集されるデータには、人口統計、経済状況、居住環境など、さまざまなカテゴリの情報が含まれています。これらのデータは、政府が現状を正確に把握し、将来に向けた政策立案を行ううえで重要な基礎資料となります。本記事では、Pythonを活用してインドの国勢調査データを分析する方法を解説します。人口動態や経済指標など複数の観点からデータを掘り下げ、その結果をグラフとして視覚的に表現します。使用するデータセットはKaggleから入手した「India Districts Census 2011」です。データの準備と読み込