pickleは「オブジェクトを保存したり、読み込んだりできる」モジュールです。
pythonの変数はオブジェクトでできているので、pickleを使うことでリテラルやリスト、インスタンスなど、あらゆるデータをシリアライズして保存できるようになります。
ここでは「pickleって何?」「pickleの使い方が知りたい」といった方へ、pickleの使い方を解説します。
オブジェクトのシリアライズとは?
pickleの説明の前に、まず「オブジェクトのシリアライズ」って一体何?というところから解説します。
シリアライズとは「オブジェクトをバイト列にする」ことを指します。
バイト列とは1バイト単位の情報の配列のことです。バイト列にすることでオブジェクトをファイルに保存できるようになります。
また、シリアライズされているオブジェクトを元に戻すことをデシリアライズと言います。シリアライズしただけではあまり意味は無いので、シリアライズとデシリアライズはどのシステムでもセットで登場します。
余談ですが、シリアライズしたオブジェクトをファイルに保存することを永続化と言います。
pickleの基本的な使い方
pickleは標準モジュールなのでpip等でインストールする必要はありません。
初めにpickleをimportし、pickle.dump()の1つ目の引数にオブジェクトを、2つ目の引数にファイルを指定することで、指定したファイルのオブジェクトを保存できます。
[main.py]
import pickle
l = [1, 2, 3, 4, 5]
with open('pic.bin', 'wb') as p:
pickle.dump(l, p)
これでpythonファイルと同じ階層にpic.binファイルが作成され、中にリストが格納されます。
pickleはバイナリ形式でオブジェクトを保存するので、ファイルをオープンする際のmodeにbを追加し、バイナリモードにする必要があります(ちなみに.binはバイナリファイルにつけられる一般的な拡張子です)。
次に保存したリストを別の場所で読み込んでみましょう。 main2.pyを作成して次のコードを実行します。
[main2.py]
import pickle
with open('pic.bin', 'rb') as p:
l = pickle.load(p)
print(l)
[出力結果]
[1, 2, 3, 4, 5]
main.pyで保存したリストをmain2.pyで読み込めました。
保存したオブジェクトを読み込む場合はpickle.load()を使います。
ファイルライクオブジェクトを使う
上記の方法では一度pic.binファイルにバイナリ形式でオブジェクトを保存し、それを別の場所から読み込むという工程を取りましたが、一々ファイルを介する必要があるのは少々面倒です。
特に永続化する必要が無い場合はファイルライクオブジェクトであるBytesIOを使うことで、ファイルを作ることなくファイルと同じようなオブジェクトを扱えます。
import pickle
import io
file = io.BytesIO()
dic = {'1':'a', '2':'b'}
pickle.dump(dic, file)
file.seek(0)
dic2 = pickle.load(file)
print(dic2)
[出力結果]
{'1': 'a', '2': 'b'}
BytesIOはioモジュール内にあるので、ioをimportしています。
BytesIO()で作ったファイルオブジェクトをpickle.dumpの2つ目の引数に渡すことで、通常のファイルと同じ役割をしてくれます。
途中seek()という関数を使っていますが、これは0を渡すことでストリームの位置を先頭にしています。これをしないとloadのタイミングでエラーになるので注意しましょう。