Pythonプログラムで生成したクラスのインスタンスやリスト、辞書などの複雑なデータを、そのままの形でファイルに保存(シリアライズ)し、後から復元(デシリアライズ)したい場合は、標準ライブラリの pickle モジュールを使用します。
JSON形式とは異なり、自作クラスのインスタンスなども型情報を保ったまま保存できるため、一時的なデータの退避や、機械学習モデルの保存などに広く利用されます。
目次
実装例:RPGのセーブデータ管理
ここでは、ゲームのキャラクター情報(名前、職業、レベル)を持つオブジェクトを作成し、それをバイナリファイルとして保存・復元する「セーブ&ロード」機能を実装します。
ソースコード
import pickle
# 1. 保存したいデータ構造(クラス)を定義
class GameCharacter:
def __init__(self, name, job, level):
self.name = name
self.job = job
self.level = level
def __str__(self):
return f"[{self.job}] {self.name} (Lv.{self.level})"
def level_up(self):
self.level += 1
print(f">> {self.name} はレベルが上がった!")
# --- メイン処理 ---
# 2. インスタンスの生成(実行中のデータ)
hero = GameCharacter("アルス", "勇者", 45)
print("--- 現在の状態(保存前) ---")
print(hero)
# 3. データをファイルに保存(シリアライズ)
# pickleはバイナリ形式のため、必ず 'wb' (Write Binary) モードで開きます
save_file = "adventure_log.pkl"
with open(save_file, "wb") as f:
# pickle.dump(保存するオブジェクト, ファイルオブジェクト)
pickle.dump(hero, f)
print(f"\n>> 冒険の書 '{save_file}' に記録しました。")
print("-" * 30)
# 4. データをファイルから読み込み(デシリアライズ)
# 読み込み時も 'rb' (Read Binary) モード必須です
with open(save_file, "rb") as f:
# pickle.load(ファイルオブジェクト) で元のオブジェクトに戻ります
loaded_hero = pickle.load(f)
print("--- 復元したデータ(ロード後) ---")
print(loaded_hero)
# 復元したオブジェクトが元の機能(メソッド)を保持しているか確認
loaded_hero.level_up()
print(f"更新後の状態: {loaded_hero}")
実行結果
--- 現在の状態(保存前) ---
[勇者] アルス (Lv.45)
>> 冒険の書 'adventure_log.pkl' に記録しました。
------------------------------
--- 復元したデータ(ロード後) ---
[勇者] アルス (Lv.45)
>> アルス はレベルが上がった!
更新後の状態: [勇者] アルス (Lv.46)
解説
pickleの仕組み
- シリアライズ (
dump): Python上のオブジェクト(メモリ上のデータ)を、保存や転送が可能な「バイト列」に変換することです。 - デシリアライズ (
load): バイト列から元のPythonオブジェクトを再構築することです。
重要な注意点
- バイナリモード (
wb,rb):pickleが扱うデータはテキストではなくバイナリデータです。open()関数では必ずbを付加したモードを指定してください。 - セキュリティリスク:
pickle.load()は、悪意のある細工がされたファイルを読み込むと任意のコードを実行されてしまう危険性があります。信頼できないソース(知らない人から送られてきたファイルなど)から受け取ったpickleファイルは絶対に読み込まないでください。 - JSONとの違い:
- JSON: テキスト形式。他言語との互換性が高いが、保存できる型に制限がある(自作クラスなどは変換が必要)。
- Pickle: バイナリ形式。Python専用だが、ほぼすべてのPythonオブジェクトをそのまま保存できる。
