web-dev-qa-db-ja.com

pickle-ファイルに複数のオブジェクトを入れますか?

多数のピクルスされたオブジェクト(実際にはタプル)をファイルにダンプするメソッドがあります。

それらを1つのリストに入れたくありません。同じファイルに何度もダンプしたいのです。私の問題は、どのようにオブジェクトを再びロードするのですか?最初と2番目のオブジェクトは1行の長さなので、これはreadlinesで機能します。しかし、他のすべてはより長いです。当然、試してみると

myob = cpickle.load(g1.readlines()[2])

g1がファイルの場合、ピクルされたオブジェクトが1行より長いため、EOFエラーが発生します。ピクルされたオブジェクトだけを取得する方法はありますか?

24
newnewbie

ファイルハンドルを直接pickleに渡すと、望む結果を得ることができます。

import pickle

# write a file
f = open("example", "w")
pickle.dump(["hello", "world"], f)
pickle.dump([2, 3], f)
f.close()

f = open("example", "r")
value1 = pickle.load(f)
value2 = pickle.load(f)
f.close()

pickle.dumpはファイルの末尾に追加されるため、複数回呼び出して複数の値を書き込むことができます。

pickle.loadは、ファイルから最初の値を取得するのに十分なだけ読み取り、ファイルハンドルを開いたままにして、ファイル内の次のオブジェクトの開始点を指します。 2番目の呼び出しは、2番目のオブジェクトを読み取り、ファイルの最後にファイルポインターを残します。 3番目の呼び出しは、予想どおりEOFErrorで失敗します。

この例では普通のpickleを使用しましたが、この手法はcPickleでも同じように機能します。

70
Martin Atkins

最善の方法は、データを保存する前に単一のオブジェクトにパックし、ロード後にアンパックすることだと思います。これは、タプルをコンテナとして使用する例です(you can use dict also):

a = [1,2]
b = [3,4]

with open("tmp.pickle", "wb") as f:
    pickle.dump((a,b), f)

with open("tmp.pickle", "rb") as f:
    a,b = pickle.load(f) 
17
Samuel

ファイルの行、justpickle.load()必要なオブジェクトの数としてそれらを読み戻さないでください。それを行う例については、質問に対する私の答え Pythonでオブジェクトを保存する方法 を参照してください。

1
martineau