2013-12-21 20 views
29

私はゲームでプレイヤーに役立つクラスを持っています。pickleファイルに複数のオブジェクトを保存して読み込む?

後で使用するために、これらのプレーヤーオブジェクトをファイルに保存する必要があります。 pickleモジュールを試しましたが、複数のオブジェクトを保存して再度読み込む方法がわかりません。これを行う方法はありますか、リストなどの他のクラスを使用してオブジェクトをリストに保存してロードする必要がありますか?

良い方法がありますか?

import pickle 
PIK = "pickle.dat" 

data = ["A", "b", "C", "d"] 
with open(PIK, "wb") as f: 
    pickle.dump(data, f) 
with open(PIK, "rb") as f: 
    print pickle.load(f) 

印刷される:

['A', 'b', 'C', 'd'] 

をしかし、ピクルスファイルは、いずれかを含むことができ、リスト、タプル、または辞書をはるかにこれを行うための最も一般的な方法です使用

+2

使用 'コンテナとしてlist'は合理的であると思われます。 – falsetru

答えて

39

ピクルスの数。同じ出力を生成するコードは次のとおりです。しかし、それは書くことと理解することが難しくなりますのでご注意:

with open(PIK, "wb") as f: 
    pickle.dump(len(data), f) 
    for value in data: 
     pickle.dump(value, f) 
data2 = [] 
with open(PIK, "rb") as f: 
    for _ in range(pickle.load(f)): 
     data2.append(pickle.load(f)) 
print data2 

あなたがこれを行う場合、あなたは多くの漬物はあなたが書き出すファイルであるかを知るための責任があります。上のコードは、リストオブジェクトの数を最初にpicklingすることによってそれを行います。

+0

ありがとう私はあなたのアイデアを持っていますが、メモリの問題を引き起こす可能性のある複数のリストオブジェクトを考えたので、各プレーヤーを別々のファイルに保存することにしましたが、 –

+1

十分な情報がありません。何人の選手?どのプレイヤーのピクルスはどれくらいの大きさですか?使用可能なRAMの容量はどれくらいですか?非常に多くのプレイヤーがいる場合は、データベースを組み込んで、その中にピクルスを保存することをお勧めします(独自のデータベースを作成するのではなく、一度に1つの苦しいステップ)。 –

+1

すべてのpickleの例は常にバイナリモードを使用しますか?バイナリファイルの書き込みは、私の仕事がまだブローチされていない1つのフロンティアです。私はそれについて何も知りません。 – Aerovistae

57

Tim Peters' accepted answerへの2つの追加。

まず、あなたがロードするため、次のイディオムを使用する場合は、別途漬けのアイテム数は保管しない必要があります。

def load(filename): 
    with open(filename, "rb") as f: 
     while True: 
      try: 
       yield pickle.load(f) 
      except EOFError: 
       break 

items = load(myfilename) 

第二、この方法を、あなたがリストを取得しないではなく、 a generator。 ダンプされたデータが非常に大きい場合は、一度に1つのアイテムしかメモリにロードされません。 ダッシュされたデータが非常に大きい場合、 が最初に別個にピケッとした可能性があります。 itemsを繰り返し実行して、forというループを のようにループすることができます。

+0

これはちょうどあなたが結果を反復処理するまで '負荷(myfilename)呼び出しは'実際にデータをロードしたり、ファイルから読み取らないことに注意してトップの答え –

+0

でなければなりません。すぐにロードしたい場合は、 'list(load(myfilename))'や 'for'ループのようなものを使用してください。 – drevicko

3

私は1つまたは複数のobjectを保存し、復元するpickleを使用してオブジェクト指向のデモを行います:

class Worker(object): 

    def __init__(self, name, addr): 
     self.name = name 
     self.addr = addr 

    def __str__(self): 
     string = u'[<Worker> name:%s addr:%s]' %(self.name, self.addr) 
     return string 

# output one item 
with open('testfile.bin', 'wb') as f: 
    w1 = Worker('tom1', 'China') 
    pickle.dump(w1, f) 

# input one item 
with open('testfile.bin', 'rb') as f: 
    w1_restore = pickle.load(f) 
print 'item: %s' %w1_restore 

# output multi items 
with open('testfile.bin', 'wb') as f: 
    w1 = Worker('tom2', 'China') 
    w2 = Worker('tom3', 'China') 
    pickle.dump([w1, w2], f) 

# input multi items 
with open('testfile.bin', 'rb') as f: 
    w_list = pickle.load(f) 

for w in w_list: 
    print 'item-list: %s' %w 

出力:

item: [<Worker> name:tom1 addr:China] 
item-list: [<Worker> name:tom2 addr:China] 
item-list: [<Worker> name:tom3 addr:China] 
0

をごkleptoを使用する場合、それはあなたに与える、簡単ですファイルやデータベースにオブジェクトを透過的に格納する機能。 dict APIを使用して、dumpおよび/またはloadのアーカイブからの特定のエントリ(以下のケースでは、シリアライズされたオブジェクトはファイルごとに1つのエントリがscoresという名前で格納されます)を許可します。

>>> import klepto 
>>> scores = klepto.archives.dir_archive('scores', serialized=True) 
>>> scores['Guido'] = 69 
>>> scores['Fernando'] = 42 
>>> scores['Polly'] = 101 
>>> scores.dump() 
>>> # access the archive, and load only one 
>>> results = klepto.archives.dir_archive('scores', serialized=True) 
>>> results.load('Polly') 
>>> results 
dir_archive('scores', {'Polly': 101}, cached=True) 
>>> results['Polly'] 
101 
>>> # load all the scores 
>>> results.load() 
>>> results['Guido'] 
69 
>>> 
0

これを試してみてください:

import pickle 

file = open('test.pkl','wb') 
obj_1 = ['test_1', {'ability', 'mobility'}] 
obj_2 = ['test_2', {'ability', 'mobility'}] 
obj_3 = ['test_3', {'ability', 'mobility'}] 

pickle.dump(obj_1, file) 
pickle.dump(obj_2, file) 
pickle.dump(obj_3, file) 

file.close() 

file = open('test.pkl', 'rb') 
obj_1 = pickle.load(file) 
obj_2 = pickle.load(file) 
obj_3 = pickle.load(file) 
print(obj_1) 
print(obj_2) 
print(obj_3) 
file.close() 
関連する問題