2015-10-08 61 views
1

我怎樣才能在一個文件(Python文件1)中包含一個類的實例並在另一個文件(Python文件2)中包含pickle.load的實例的字典對象?Pickle Python中的類實例字典

我有一個龐大複雜的數據集組成的幾個文件,我創建了一個類來存儲我所有的屬性。我製作了一本詞典來存儲所有的樣本和屬性。 key = sample,value =包含屬性的類的實例。下面的例子:

#Python File 1 
import random 

class Storage: 
    def __init__(self,label,x,y): 
     self.label = label; self.x = x; self.y = y 
    def get_x(self): return(self.x) 
    def get_y(self): return(self.y) 

D_var_instance = {} 
L = ["A","B","C"] 

for var in L: 
    D_var_instance[var] = Storage(label=var,x=random.random(),y=random.random()) 

print(D_var_instance["A"]) 
#<__main__.Storage instance at 0x102811128> 

print(D_var_instance["A"].get_x()) 
#0.193517721574 

我花了很長的時間與我的真實數據集,使這個,我嘗試使用picklepickle.dump字典對象,但它不工作:

#Python File 1 
import pickle 
pickle.dump(D_var_instance,open("/path/to/dump.txt","w")) 
pickle.dump(Storage, open("/path/to/storagedump.txt","w")) 

我試圖在另一個裝與此代碼的Python文件:

#Python File 2 
import pickle 
Storage = pickle.load(open("/path/to/storagedump.txt","r")) 
D_var_instance = pickle.load(open("/path/to/dump.txt","r")) 

得到這個錯誤:

AttributeError: 'module' object has no attribute 'Storage' 
+0

我希望我不需要醃一個班的每個實例......這會吸引我,因爲我有成千上萬的實例。 –

+1

是否嘗試在嘗試加載泡菜的文件中定義相同的'Storage'類?另外,您應該打開文件以使用二進制模式('b')讀/寫醃菜。 –

+0

我只是複製粘貼你的代碼,我沒有得到你的錯誤。我收到了這個輸出:'{'A':<__ main__.Storage實例在0x10a128998>,'C':<__ main__.Storage實例在0x10a1289e0>,'B':<__ main__.Storage實例在0x10a128a28>}' – idjaw

回答

1

這裏的問題可以通過這個完美地解釋SO發佈權here

最終,這裏發生了什麼,就是當你爲酸洗的情況下,你必須能夠相對於適當引用您的模塊你從哪裏醃製它。

所以,展示一些代碼來說明這一點。你可以這樣做(下面再說明):

storage.py

class Storage(object): 
    pass 

foo.py

import pickle 
from storage import Storage 

D_var_instance = {} 
L = ["A","B","C"] 

for var in L: 
    D_var_instance[var] = Storage(label=var,x=random.random(),y=random.random()) 

pickle.dump(D_var_instance, open("/path/pickle.txt", "wb")) 

boo.py

D_var_instance = pickle.load(open("/path/pickle.txt", "rb")) 

所以,當你寫你的醃菜,從foo開始,你的參考文獻現在是storage.Storage。當你進入一個完全不同的模塊(boo.py)並試圖解開時,這裏發生的事情是,你正在嘗試加載一個引用某個模塊的東西,而這個模塊從你所從之處不起作用。

解決此問題的方法現在可以通過不同的方式完成。由於我將所有內容組織在同一層,所以實際上你不需要導入任何東西,它應該可以工作!

但是,如果你碰巧有你的類和鹹菜寫在同一模塊中,像你這樣,那麼你將不得不進口,容納在boo.py

代碼我建議你看一下這兩個模塊我在SO帖子中提供的選項鍊接到哪一個可以滿足您。但是這應該是你的解決方案。

從IPython的產量運行此腳本:

ipython boo.py 
{'A': <storage.Storage instance at 0x1107b77e8>, 'C': <storage.Storage instance at 0x1107b7680>, 'B': <storage.Storage instance at 0x1107b7908>} 
+0

感謝您看看它!你可以在iPython筆記本電腦中做這個嗎?如果foo.py實際上是iPyhon筆記本。 –

+0

@ O.rka看看我更新它。如果你願意,我們可以進一步討論。 – idjaw

2

您可以通過使用dill代替pickle可以很容易對自己。dill pickles類定義以及類實例(而不是引用,如pickle一樣)。所以,除了import dill as pickle之外,您不需要做任何其他的事情。

爲了模擬在另一個文件中工作,我將在一個字典中構建一個類,一些類實例,然後刪除除醃製字符串之外的所有東西。你可以從那裏重建。

>>> class Foo(object): 
... def __init__(self, x): 
...  self.x = x 
... 
>>> d = dict(f=Foo(1), g=Foo(2), h=Foo(3)) 
>>> 
>>> import dill 
>>> _stored_ = dill.dumps(d) 
>>>   
>>> del Foo 
>>> del d 
>>> 
>>> d = dill.loads(_stored_) 
>>> d['f'].x 
1 
>>> d['g'].x 
2 
>>> d['h'].x 
3 
>>> dill.dump_session() 

我完成了dump_session,鹹菜中解釋到一個文件中的一切。然後,在一個新的python會話中(可能在不同的機器上),你可以啓動你離開的地方。

>>> import dill 
>>> dill.load_session() 
>>> d 
{'h': <__main__.Foo object at 0x110c6cfd0>, 'g': <__main__.Foo object at 0x10fbce410>, 'f': <__main__.Foo object at 0x110c6b050>} 
>>> 

如果您正在尋找傳統dumpload,那也可以。它也適用於ipython

+0

感謝您的幫助,但我不得不標記其他答案,因爲他已經與我一起工作了一個多小時。我一定會研究蒔蘿。這看起來像是對我來說非常有用的東西。 –

+2

我這樣看待它:爲什麼只需一次導入就可以解決您的問題,然後再重新編碼一小時或更長時間?但每一個他自己。我是'蒔蘿'作家,所以如果你嘗試'蒔蘿'並遇到任何困難,請發佈一個問題。 –

+0

@MikeMcKerns直到最近我才知道蒔蘿。做得好。只是想讓你知道!乾杯。 – idjaw