Python pickle.dump()・load()の使い方|wb/rbの書き方と、Ran out of input・No module namedの直し方
pickle.dump(オブジェクト, ファイル) でPythonのオブジェクトをファイルに保存し、pickle.load(ファイル) で元に戻します。ファイルは必ずバイナリモードで開き、保存は “wb”、読み込みは “rb” を指定します。
この記事では、dump()とload()の引数と書き方、複数のオブジェクトの保存と追記、そして「EOFError: Ran out of input」「No module named」「invalid load key」など、dump()・load()で実際に出るエラーの原因と直し方を、実行結果つきで説明します。実行環境はPython 3.12.15です(2026年10月18日確認)。
pickleとは何か、JSONとの違いや安全性の話は「Python pickleとは?使い方(保存・読み込み)とJSONとの違い・危険性の注意点」、ファイルを使わずにバイト列にするdumps()・loads()は「Python pickle.dumps()・loads()の使い方」で扱っています。ここではファイルに保存するdump()とload()に絞ります。
dump()とload()の基本の書き方
import pickle
data = {"name": "田中", "scores": [80, 95]}
with open("data.pkl", "wb") as f:
pickle.dump(data, f)
with open("data.pkl", "rb") as f:
loaded = pickle.load(f)
print(loaded)
実行結果:
{'name': '田中', 'scores': [80, 95]}
辞書・リスト・数値・文字列だけでなく、自作クラスのインスタンスや、pandasのDataFrame、学習済みの機械学習モデルなども同じ書き方で保存できます。拡張子に決まりはありませんが、.pklや.pickleがよく使われます。
dump()・load()の引数
公式ドキュメント(pickle — Python documentation、2026年10月18日確認)での定義は次のとおりです。
pickle.dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None)
pickle.load(file, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None)
| 引数 | 使う関数 | 意味 |
|---|---|---|
obj |
dump | 保存するオブジェクト(1番目) |
file |
dump・load | バイナリモードで開いたファイル(dumpでは2番目) |
protocol |
dump | 保存形式のバージョン。省略するとpickle.DEFAULT_PROTOCOL |
encoding |
load | Python 2で作られたpickleを読むときだけ使う |
load()にはprotocolを指定する引数がありません。読み込むときは、どのprotocolで保存されたかが自動で判別されます。
既定のprotocolは、Python 3.8〜3.13では4、Python 3.14からは5です(公式ドキュメント)。Python 3.12で確かめると次のとおりです。
print(pickle.DEFAULT_PROTOCOL, pickle.HIGHEST_PROTOCOL)
実行結果:
4 5
protocol 5はPython 3.8から読めるので、3.7以前で読む必要があるファイルはprotocol=4などを指定して保存します。各protocolの違いは「Python pickleのprotocolとは?バージョンの違いと選び方」を参照してください。
複数のオブジェクトを保存する・追記する
1つのファイルにdump()を何度も呼べば、複数のオブジェクトを保存できます。"ab"(追記+バイナリ)で開けば、あとから足すこともできます。
import pickle
with open("log.pkl", "wb") as f:
pickle.dump({"id": 1}, f)
for i in (2, 3):
with open("log.pkl", "ab") as f:
pickle.dump({"id": i}, f)
items = []
with open("log.pkl", "rb") as f:
while True:
try:
items.append(pickle.load(f))
except EOFError:
break
print(items)
実行結果:
[{'id': 1}, {'id': 2}, {'id': 3}]
pickleファイルには「いくつ入っているか」が記録されないので、読み込む側はEOFErrorが出るまでload()を繰り返します。追記の必要がなければ、最初からリストにまとめて1回のdump()で保存するほうが扱いやすくなります。"wb"で開くとファイルは空にされてから書き込まれるので、上書きと追記を取り違えないようにしてください。
dump()・load()で出るエラーと直し方
実際に出たエラーメッセージを、原因ごとにまとめます。
| エラーメッセージ | 原因 | 直し方 |
|---|---|---|
TypeError: write() argument must be str, not bytes |
dump()するファイルを"w"で開いた |
"wb"で開く |
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 ... |
load()するファイルを"r"で開いた |
"rb"で開く |
TypeError: file must have a 'write' attribute |
dump()の引数の順番が逆 | dump(オブジェクト, ファイル)の順にする |
EOFError: Ran out of input |
ファイルが空、または入っている数より多く読んだ | 保存処理が最後まで動いたか確認する |
_pickle.UnpicklingError: invalid load key, '{'. |
pickleではないファイル(JSONやテキスト)を読んだ | 読むファイルを確認する |
ModuleNotFoundError: No module named 'models' |
保存したクラスのモジュールが読み込む側で見つからない | 同じモジュールをimportできる場所で読む |
AttributeError: Can't get attribute 'Point' on <module '__main__' ...> |
スクリプト本体で定義したクラスを、別のスクリプトで読んだ | クラスを別ファイルのモジュールに移す |
TypeError: cannot pickle '_thread.lock' object |
ロックやファイル、通信などpickleできないものが入っている | 保存する前に取り除く |
EOFError: Ran out of input
検索でいちばん多いエラーです。空のファイルを読んだときと、1つしか入っていないファイルを2回読んだときに、どちらも同じメッセージになります。
import pickle
open("empty.pkl", "wb").close()
try:
with open("empty.pkl", "rb") as f:
pickle.load(f)
except EOFError as e:
print("EOFError:", e)
実行結果:
EOFError: Ran out of input
空のファイルができる典型は、open("data.pkl", "wb")でファイルを開いた直後にdump()がエラーで止まった場合です。"wb"は開いた時点で中身を消すので、保存に失敗すると空のファイルだけが残ります。大事なデータは別名で保存してから置き換える、あるいはキャッシュ用途なら読み込みに失敗したら作り直す、という書き方にしておくと安全です。
try:
with open("cache.pkl", "rb") as f:
data = pickle.load(f)
except (FileNotFoundError, EOFError, pickle.UnpicklingError):
data = build_data() # 作り直す処理(自分で用意する関数)
EOFErrorそのものの意味は「Python EOFErrorとは?入力が尽きたときの原因と対処法」で説明しています。
No module named / Can’t get attribute(自作クラスが読めない)
pickleはクラスの中身(コード)を保存していません。保存されるのは「どのモジュールのどのクラスか」という名前と、属性の値だけです。読み込むときにはその名前でクラスを探すので、見つからないとエラーになります。
models.pyに定義したPointクラスを保存し、models.pyがないフォルダで読み込んだ結果です。
ModuleNotFoundError: No module named 'models'
保存するスクリプトの中で直接クラスを定義した場合は、クラスが__main__の中にあると記録されます。別のスクリプトで読み込むと、そのスクリプトの__main__にはクラスがないため、次のエラーになります(パスの部分は省略しています)。
AttributeError: Can't get attribute 'Point' on <module '__main__' from '.../load_main.py'>
どちらも、クラスをmodels.pyのような別ファイルに置き、保存する側と読み込む側の両方からimportできるようにすれば解決します。クラス名やモジュール名を変えると古いpickleファイルが読めなくなるので、長く保存するデータには注意してください。
pickleできないオブジェクト
import pickle, threading
try:
with open("x.pkl", "wb") as f:
pickle.dump({"lock": threading.Lock()}, f)
except TypeError as e:
print("TypeError:", e)
try:
with open("x.pkl", "wb") as f:
pickle.dump(lambda x: x, f)
except pickle.PicklingError as e:
print("PicklingError:", e)
実行結果:
TypeError: cannot pickle '_thread.lock' object
PicklingError: Can't pickle <function <lambda> at 0x1018aa5c0>: attribute lookup <lambda> on __main__ failed
ロック、開いたファイル、ソケットなどの通信、lambda式は保存できません。Python 3.14からは、どの部分が原因かを示す説明(例外ノート)がエラーに付くようになりました(What’s New In Python 3.14、2026年10月18日確認)。また、Python 3.15ではプライベートメソッドと入れ子のクラスもpickleできるようになっています(What’s New In Python 3.15、2026年10月18日確認)。
load()するファイルは信頼できるものだけ
公式ドキュメントは冒頭で、pickleは安全ではなく、細工されたデータを読み込むと任意のコードが実行されうるので、信頼できないところから来たデータはload()しないよう警告しています。自分で保存したファイル以外を読む用途では、JSONなど別の形式を使ってください。詳しくは「Python pickleは危険?脆弱性の仕組みと安全に扱う方法」で説明しています。
よくある質問
Q. pickle.dump()の引数の順番は?
pickle.dump(保存するオブジェクト, ファイル) の順です。逆にすると TypeError: file must have a ‘write’ attribute になります。json.dump() と同じ順番です。
Q. pickle.load()でEOFError: Ran out of inputが出ます。
ファイルが空か、入っているオブジェクトの数より多く load() しています。保存処理が途中で止まって空のファイルが残っていないか、ファイルサイズを確認してください。複数入っている場合は EOFError が出るまで繰り返し読みます。
Q. pickleファイルを別のPCで読むとNo module namedになります。
保存したオブジェクトのクラスが入っているモジュールが、読み込む側にないためです。同じモジュールを用意し、import できる場所で読み込んでください。
Q. pickleに追記するには?
ファイルを “ab” で開いて dump() します。読み込むときは EOFError が出るまで load() を繰り返します。”wb” で開くと既存の中身は消えます。
まとめ
- 保存は
pickle.dump(obj, f)("wb")、読み込みはpickle.load(f)("rb") - 既定のprotocolは3.13までは4、3.14から5。load()は自動で判別する
- 複数保存・追記はできるが個数は記録されない。EOFErrorで終わりを判断
- Ran out of input は「空のファイル」か「読みすぎ」
- 自作クラスは読み込む側でもimportできる場所に置く
- 信頼できないpickleファイルはload()しない
pandasのDataFrameを保存するなら、専用のto_pickle()・read_pickle()も使えます(「pandasのto_pickle・read_pickleの使い方」)。
エラーメッセージから原因をたどる力は、実際にコードを書いて詰まった経験から身につきます。テックジムは永田町の東京本校などに通って学ぶ対面型のプログラミングスクールで、自分のペースで課題を進め、分からないところはトレーナーに質問できます。まずは無料Python講座(ゼロからはじめるPython入門講座)から試すこともできます。


