2013-05-19 150 views
1

我正在對一個實例變量進行一些計算,之後完成了,我想醃一下類實例,這樣我就不必再做計算了。下面一個例子:Python pickle實例變量

test.compute(6)
import cPickle as pickle 

class Test(object): 
    def __init__(self, a, b): 
     self.a = a 
     self.b = b 
     self.c = None 
    def compute(self, x): 
     print 'calculating c...' 
     self.c = x * 2 

test = Test(10, 'hello') 
test.compute(6) 

# I have computed c and I want to store it, so I don't have to recompute it again: 

pickle.dump(test, open('test_file.pkl', 'wb')) 

後,我可以檢查,看看有什麼test.__dict__是:

>>> test.__dict__ 
{'a': 10, 'c': 12, 'b': 'hello'} 

我認爲這是什麼會得到醃;然而,

當我去加載類的實例:

import cPickle as pickle 

from pickle_class_object import Test 

t2 = pickle.load(open('test_file.pkl', 'rb')) 

我看到這個在shell:

calculating c... 

這意味着我沒有鹹菜c,我在計算過程中再次。

有沒有辦法泡菜test我想怎麼做?所以我不必再次計算c。我看到我可以醃製test.__dict__,但我想知道是否有更好的解決方案。另外,我對這裏發生的事情的理解很薄弱,所以對發生的事情發表任何評論都會很棒。我已閱讀__getstate____setstate__,但我不知道如何在這裏應用它們。

回答

2

酸洗工作正如你所期望的那樣。這裏的問題是,當您運行新腳本時,您將導入包含類Test的模塊。整個模塊正在運行,包括您創建的位test

處理這類事情的典型方法是保護if __name__ == "__main__:塊中的東西。

class Test(object): 
    def __init__(self, a, b): 
     self.a = a 
     self.b = b 
     self.c = None 
    def compute(self, x): 
     print 'calculating c...' 
     self.c = x * 2 

if __name__ == "__main__": 
    import cPickle as pickle 

    test = Test(10, 'hello') 
    test.compute(6) 

    # I have computed c and I want to store it, so I don't have to recompute it again: 

    pickle.dump(test, open('test_file.pkl', 'wb')) 
3

你又導入pickle_class_object模塊,和Python運行該模塊中的所有代碼。

您的頂層模塊代碼包含對.compute()的調用,即調用的內容。

您可能需要移動創建的泡菜出模塊代碼,或將其移動到if __name__ == '__main__':把守部分:運行一個python文件時

if __name__ == '__main__': 
    test = Test(10, 'hello') 
    test.compute(6) 

    pickle.dump(test, open('test_file.pkl', 'wb')) 

只有作爲主腳本是__name__設置爲__main__;當作爲模塊導入時,__name__將被設置爲模塊名稱,而if分支將不會運行。

1

這不是發生了什麼事情。你導入一個python模塊,它在頂層有一個代碼,當你導入模塊時會執行它。你可以看到你的代碼工作,你打算:

import cPickle as pickle 

class Test(object): 
    def __init__(self, a, b): 
     self.a = a 
     self.b = b 
     self.c = None 
    def compute(self, x): 
     print 'calculating c...' 
     self.c = x * 2 

test = Test(10, 'hello') 
test.compute(6) 

pickle.dump(test, open('test_file.pkl', 'wb')) 

t2 = pickle.load(open('test_file.pkl', 'rb')) 
print t2.c 


--output:-- 
calculating c... 
12 

如果你的代碼工作,你形容,那麼你會看到「計算Ç...」兩次。