Pythonで複数の変数を保存および復元するにはどうすればよいですか?


104

約12個のオブジェクトをファイルに保存して、後で復元する必要があります。forleループをpickleとshelveで使用しようとしましたが、正しく機能しませんでした。

編集。
保存しようとしていたすべてのオブジェクトは同じクラスにありました(これについては以前に触れたはずです)。クラス全体を次のように保存できることを理解していませんでした。

import pickle
def saveLoad(opt):
    global calc
    if opt == "save":
        f = file(filename, 'wb')
        pickle.dump(calc, f, 2)
        f.close
        print 'data saved'
    elif opt == "load":
        f = file(filename, 'rb')
        calc = pickle.load(f)
    else:
        print 'Invalid saveLoad option'

1
あなたはforループを試したと言います。そのコードを投稿してください、そして「なぜうまくいかなかったのか」(つまり、何が起こったのか、何が起こりたかったのか)。
ブレア

Windowsを使用している場合は、ファイルを必ずバイナリモードで開いてください
John La Rooy

@gnibbler:バイナリモードは、デフォルト以外のプロトコル(docs.python.org/library/pickle.html#usage)でのみ必要です。
エリックOレビゴット

回答:


170

複数のオブジェクトを保存する必要がある場合は、それらを単一のリストまたはタプルに単純に配置できます。たとえば、次のようにします。

import pickle

# obj0, obj1, obj2 are created here...

# Saving the objects:
with open('objs.pkl', 'w') as f:  # Python 3: open(..., 'wb')
    pickle.dump([obj0, obj1, obj2], f)

# Getting back the objects:
with open('objs.pkl') as f:  # Python 3: open(..., 'rb')
    obj0, obj1, obj2 = pickle.load(f)

大量のデータがある場合は、に渡しprotocol=-1てファイルサイズを減らすことができますdump()pickle次に、デフォルトの履歴(および下位互換性)プロトコルの代わりに、利用可能な最良のプロトコルを使用します。この場合、ファイルは、(バイナリモードでオープンされなければならないwbrb、それぞれ)。

バイナリモードはPython 3でも使用する必要があります。デフォルトのプロトコルではバイナリ(つまり、非テキスト)データ(書き込みモード'wb'と読み取りモード'rb')が生成されるためです。


12
Python 3.5では、たとえば「バイト」モードでファイルを開く必要がありましたwith open('objs.pickle', 'wb') as f:(に注意してくださいwb)。
kbrose 2016年

こんにちは@Eric、with open('objs.pkl') as f:単純に比較する必要は何obj1, obj2 = pickle.load(open("objs.pkl","rb"))ですか?これらの2つの間に違いはありますか?
balandongiv

2番目のフォームでは、ファイルを閉じません。並行して開くことができるファイルの数は通常、オペレーティングシステムによってかなり制限されるため、これは良い方法とは見なされません(ファイルを閉じずに開くループを試してください!)。とは言っても、実際には、多くのファイルを開かないときに、ファイルを閉じないことがよく機能します。
エリックOレビゴ

49

と呼ばれる組み込みライブラリがありpickleます。を使用pickleすると、オブジェクトをファイルにダンプし、後でロードできます。

import pickle

f = open('store.pckl', 'wb')
pickle.dump(obj, f)
f.close()

f = open('store.pckl', 'rb')
obj = pickle.load(f)
f.close()

1
Python 3.4を使用:f = open('store.pckl', 'wb')書き込み先のファイルを開きます。stackoverflow.com/questions/13906623/…を参照してください。 また、 `f = open( 'store.pckl'、 'rb')を使用して、読み取るファイルを開きます。stackoverflow.com/questions/7031699/…を参照してください。
user3731622

これは3.4以降に固有ですか?'b'を使用しないとエラーが発生するので、私はほとんど回答に反対票を投じました。
Wilmer E. Henao

12

あなたは漬物のモジュールを見るべきです。大量のデータを保存する必要がある場合は、データベースを使用することをお勧めします


クラウドサーバーにログインする単一のオブジェクトを保存したいのですが、時間をかけて何度もログインした場合にサーバーがリクエストを拒否します。pickleモジュールを使用してオブジェクトをファイルにダンプすると、セキュリティ上の問題が発生する可能性がありますか?たとえば、ダンプされたオブジェクトを誰かが取得した場合、パスワードを使用せずに私のクラウドストレージにログインできます。
アルパー

5

複数の変数をpickleファイルに保存する別の方法は次のとおりです。

import pickle

a = 3; b = [11,223,435];
pickle.dump([a,b], open("trial.p", "wb"))

c,d = pickle.load(open("trial.p","rb"))

print(c,d) ## To verify

4

kleptoメモリ、ディスク、またはデータベースへの永続的なキャッシュを提供するを使用できます。

dude@hilbert>$ python
Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from klepto.archives import file_archive
>>> db = file_archive('foo.txt')
>>> db['1'] = 1
>>> db['max'] = max
>>> squared = lambda x: x**2
>>> db['squared'] = squared
>>> def add(x,y):
...   return x+y
... 
>>> db['add'] = add
>>> class Foo(object):
...   y = 1
...   def bar(self, x):
...     return self.y + x
... 
>>> db['Foo'] = Foo
>>> f = Foo()
>>> db['f'] = f  
>>> db.dump()
>>> 

次に、インタプリタの再起動後...

dude@hilbert>$ python
Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from klepto.archives import file_archive
>>> db = file_archive('foo.txt')
>>> db
file_archive('foo.txt', {}, cached=True)
>>> db.load()
>>> db
file_archive('foo.txt', {'1': 1, 'add': <function add at 0x10610a0c8>, 'f': <__main__.Foo object at 0x10510ced0>, 'max': <built-in function max>, 'Foo': <class '__main__.Foo'>, 'squared': <function <lambda> at 0x10610a1b8>}, cached=True)
>>> db['add'](2,3)
5
>>> db['squared'](3)
9
>>> db['f'].bar(4)
5
>>> 

ここでコードを取得:https : //github.com/uqfoundation


7
OPは組み込みを要求しませんでした。
Mike McKerns、

4

次のアプローチは単純に思われ、さまざまなサイズの変数で使用できます。

import hickle as hkl
# write variables to filename [a,b,c can be of any size]
hkl.dump([a,b,c], filename)

# load variables from filename
a,b,c = hkl.load(filename)

hickleパッケージは、よりも堅牢で(エラーが発生しにくく)、さらにシンプルです(コードが少ない)pickle
user2340939
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.