9.1 pickle
の紹介
モジュール pickle
はほとんどのPythonオブジェクトをファイルや文字列に保存し、その後元の状態に戻すことができるんだよ。pickle
はカスタムクラスのオブジェクトも含め、多くのデータタイプをサポートしていて、オブジェクトをバイト形式に変換したり、その逆をしたりするプロセスを自動化してくれる。
pickle
モジュールの主な関数
-
ファイルへのオブジェクトの読み書き
-
pickle.dump(obj, file)
: オブジェクトobj
をシリアライズして、 開いているファイルfile
に書き込む。 -
pickle.load(file)
: ファイルfile
からデシリアライズしたオブジェクトを読み込む。
-
-
バイト配列へのオブジェクトの読み書き
-
pickle.dumps(obj)
: オブジェクトobj
をシリアライズして、 バイトオブジェクトとして返す。 -
pickle.loads(bytes)
: バイトオブジェクトからデシリアライズしたオブジェクトを返す。
-
以下でこれらをもう少し詳しく説明するね:
9.2 ファイルへのシリアライズ
ファイルへのシリアライズの基本的な手順:
-
バイト書き込みモードでファイルを開く
(wb)
. -
オブジェクトをシリアライズするための
pickle.dump(obj, file)
を使用する。 -
オブジェクトをデシリアライズするための
pickle.load(file)
を使用する。 - ファイルを閉じる。
ファイルにおけるオブジェクトのシリアライズとデシリアライズ
基本的にはpickle
は何をシリアライズするか気にしないんだ。例えば、リストのシリアライズはこんな感じだよ:
import pickle
data = [1, 2, 3, 4, 5]
# リストのシリアライズをファイルに
with open('list.pkl', 'wb') as file:
pickle.dump(data, file)
# ファイルからリストをデシリアライズ
with open('list.pkl', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data) # 出力: [1, 2, 3, 4, 5]
そして、辞書オブジェクトのシリアライズはこんな感じ:
import pickle
# シリアライズ用のオブジェクト例
data = {'name': 'Alice', 'age': 30, 'is_student': False}
# オブジェクトをファイルにシリアライズ
with open('data.pkl', 'wb') as file:
pickle.dump(data, file)
# ファイルからオブジェクトをデシリアライズ
with open('data.pkl', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data) # 出力: {'name': 'Alice', 'age': 30, 'is_student': False}
オブジェクトを保存したい時には
dump()
を呼び出して、ロードしたい時には
load()
を呼ぶだけ。簡単だね。
9.3 文字列へのシリアライズ
オブジェクトをネットワーク経由で送信することが多いから、オブジェクトをファイルじゃなくて文字列に保存することが求められるんだ。このためにpickle
にはdumps
とloads
という、最後に追加のs
が付いたメソッドがあるんだよ。
文字列(またはバイト配列)へのシリアライズとデシリアライズの主な作業は以下の通り:
-
オブジェクトをシリアライズするために
pickle.dumps(obj)
を使用する。 -
オブジェクトをデシリアライズするために
pickle.loads(data)
を使用する。
文字列におけるオブジェクトのシリアライズとデシリアライズ
オブジェクトの文字列(またはバイトセット)へのシリアライズはさらに簡単で、dumps()
メソッドを一つ呼ぶだけ。
例:
import pickle
# シリアライズ用のオブジェクト例
data = {'name': 'Bob', 'age': 25, 'is_student': True}
# オブジェクトを文字列にシリアライズ
serialized_data = pickle.dumps(data)
print(serialized_data)
# 文字列からオブジェクトをデシリアライズ
loaded_data = pickle.loads(serialized_data)
print(loaded_data) # 出力: {'name': 'Bob', 'age': 25, 'is_student': True}
9.4 シリアライズのエラー
シリアライズの際に時々エラーが起こることがあるんだ。そんな時pickle
モジュールは例外を投げるんだ:
-
pickle.PicklingError
— シリアライズ中のエラー。 -
pickle.UnpicklingError
— デシリアライズ中のエラー。
例:
import pickle
data = {'key': 'value'}
try:
# オブジェクトをファイルにシリアライズ
with open('data.pkl', 'wb') as file:
pickle.dump(data, file)
except pickle.PicklingError as e:
print(f"シリアライズエラー: {e}")
try:
# ファイルからオブジェクトをデシリアライズ
with open('data.pkl', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data)
except pickle.UnpicklingError as e:
print(f"デシリアライズエラー: {e}")
プログラムの実行中にシリアライズ/デシリアライズのエラーが発生した場合、プログラマーとしては特にできることはないよ。ただログにエラーを保存して、後でなぜこうなったのかを調査することぐらい。
こうしたエラーの主な原因はオブジェクトのフォーマットの変更だね。ファイルにオブジェクトを保存して、その後プログラムが更新された際に新しいフィールドが追加されたり、古いフィールドが削除されたりした時なんだ。古い保存されたオブジェクトを新しいオブジェクトのクラスにロードしようとしたときに…。
また、この状況はしばしばネットワークを介したやりとりで発生する — バージョン2.18のプログラムがバージョン3.1のプログラムが期待するオブジェクトとは少し違うオブジェクトを送信するんだ。これは移行問題と呼ばれ、長期間稼働したり、需要が高いプロジェクトで頻繁に発生する。
GO TO FULL VERSION