2013-12-21 156 views
29

我有班級服務於遊戲中的玩家,創造他們和其他東西。在pickle文件中保存和加載多個對象?

我需要將這些播放器對象保存在一個文件中以便以後使用它。我嘗試過pickle模塊,但我不知道如何保存多個對象並再次加載它們?有沒有辦法做到這一點,或者我應該使用其他類如列表,並保存並加載列表中的對象?

有沒有更好的方法?

+2

使用'list'集裝箱似乎是合理的。 – falsetru

回答

39

使用列表,元組,或者字典是迄今爲止做到這一點,最常見的方式:

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'] 

然而,鹹菜文件可以包含任何醃菜數量。這裏是產生相同輸出的代碼。但是請注意,這是很難寫出和理解:

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 

如果你這樣做,你就有責任瞭解很多泡菜你怎麼寫出來的文件中。上面的代碼首先通過酸洗一些列表對象來實現這一點。

+0

謝謝我有你的想法,但我想多個列表對象,它可能會導致內存問題,我決定將每個球員保存在一個單獨的文件,但你認爲列出醃菜對象我的原因內存問題? –

+1

沒有足夠的信息。有多少玩家?每個球員的醬菜有多大?有多少內存可用?如果你有很多玩家,最好將數據庫和商店泡菜合併在一起(而不是創建自己的數據庫,這是一次一個痛苦的步驟)。 –

+1

爲什麼所有的泡菜例子總是使用二進制模式?二進制文件寫作是一個前沿,我的工作還沒有提出什麼......我對此一無所知,或者爲什麼任何人在任何地方使用它。 – Aerovistae

57

Tim Peters' accepted answer的兩個補充。

首先,你不必存放物品的數量,您單獨醃製,如果你用下面的習慣加載:

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

items = load(myfilename) 

,這樣一來,你沒有得到,但相當一個generator。 這樣一次只能將一個項目加載到內存中,如果轉儲的數據非常大,這將非常有用 - 您可能需要分開醃製多個項目的一個可能原因。 您仍然可以使用for循環遍歷items,就好像它是 的列表。

+0

這應該是最佳答案 –

+0

請注意調用'load(myfilename)'實際上並沒有加載數據或從文件中讀取,直到迭代結果爲止。如果你想立即加載它們,使用'list(load(myfilename))'或'for'循環。 – drevicko

3

我會用pickle存儲和恢復的一條或多條object給出一個面向對象的演示:

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,它給你的透明地將對象存儲在文件或數據庫中的能力。它使用一個字典API,並允許您從檔案(在下面的情況下,序列化對象在一個名爲scores的目錄中的每個文件存儲一個條目)的特定條目中提取dump和/或load

>>> 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()