2011-10-28 66 views
5

當我在unittest中使用pickle時出現錯誤。在#2python pickle上的命名空間

  1. 一類被酸洗,
  2. 爲其在#1使用類的類,
  3. 單元測試用於測試的類:

    我寫3的程序文件。

和實際代碼分別如下。

#1。 ClassToPickle.py

import pickle 
class ClassToPickle(object): 
    def __init__(self, x): 
     self.x = x 
if __name__=="__main__": 
    p = ClassToPickle(10) 
    pickle.dump(p, open('10.pickle', 'w')) 

#2。 SomeClass.py

from ClassToPickle import ClassToPickle 
import pickle 

class SomeClass(object): 
    def __init__(self): 
     self.pickle = pickle.load(open("10.pickle", 'r')) 
     self.x = self.pickle.x 
     print self.x 

if __name__ == "__main__": 
    SomeClass() 

#3。 SomeClassTest.py

import unittest 
from SomeClass import SomeClass 
from ClassToPickle import ClassToPickle # REQUIRED_LINE 

class SomeClassTest(unittest.TestCase): 
    def testA(self): 
     sc = SomeClass() 
     self.assertEqual(sc.x, 10) 

def main(): 
    unittest.main() 

if __name__ == "__main__": 
    main() 

我跑#1程序先做出泡菜文件。
然後,當我單獨運行程序文件#2(即輸入「python SomeClass.py」)時,它可以工作。
而且,當我運行程序#3單獨(即進入「蟒蛇SomeClassTest.py」),它也適用。

然而,當我在eclipse + PyDev的運行程序#3的「單元測試」,它低於返回錯誤消息。

======================================================================
ERROR: testA (SomeClassTest.SomeClassTest)
----------------------------------------------------------------------
Traceback (most recent call last):
$ File "/home/tmp/pickle_problem/SomeClassTest.py", line 9, in testA
sc = SomeClass()
$ File "/home/tmp/pickle_problem/SomeClass.py", line 8, in init
self.pickle = pickle.load(open("10.pickle", 'r'))
$ File "/usr/lib/python2.7/pickle.py", line 1378, in load
return Unpickler(file).load()
$ File "/usr/lib/python2.7/pickle.py", line 858, in load
dispatchkey
File "/usr/lib/python2.7/pickle.py", line 1090, in load_global
klass = self.find_class(module, name)
$ File "/usr/lib/python2.7/pickle.py", line 1126, in find_class
klass = getattr(mod, name)
$ AttributeError: 'module' object has no attribute 'ClassToPickle'

----------------------------------------------------------------------
Ran 1 test in 0.002s

FAILED (errors=1)

而且也,當我註釋掉那些進口ClassToPickle類(第3行程序#3和評論爲「REQUIRED_LINE」)的線,它不工作,返回下面描述的錯誤消息。

E
======================================================================
ERROR: testA (main.SomeClassTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "SomeClassTest.py", line 9, in testA
sc = SomeClass()
File "/home/tmp/pickle_problem/SomeClass.py", line 8, in init
self.pickle = pickle.load(open("10.pickle", 'r'))
File "/usr/lib/python2.7/pickle.py", line 1378, in load
return Unpickler(file).load()
File "/usr/lib/python2.7/pickle.py", line 858, in load
dispatchkey
File "/usr/lib/python2.7/pickle.py", line 1090, in load_global
klass = self.find_class(module, name)
File "/usr/lib/python2.7/pickle.py", line 1126, in find_class
klass = getattr(mod, name)
AttributeError: 'module' object has no attribute 'ClassToPickle'

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)

我想這個問題是關於蟒蛇的命名空間,但我不知道發生了什麼究竟,什麼可以解決它,我做的。

我怎樣才能#3程序正確「(在蝕+的PyDev)作爲運行單元測試」,
和在命令行而不其中進口ClassToPickle線運行#3程序?
請幫幫我。

+0

是否有另一個'ClassToPickle.py'文件可以找到它的任何地方,而不是你在這裏顯示的文件? –

+0

@ThomasK感謝您的評論,但答案是否定的。沒有在這裏顯示的三個.py文件在目錄中,我從來沒有創建名爲'ClassToPickle.py'的文件。 – fbessho

回答

6

因爲__main__.ClassToPickle != ClassToPickle.ClassToPickle,認爲它是這樣的:

當您在ClassToPickle.py腳本醃製ClassToPickle的類的實例,鹹菜模塊將醃所有的引用這意味着它將酸洗模塊名稱的類其中類的定義,因爲你執行腳本ClassToPickle.py這意味着模塊將被設置爲__main__這意味着pickle模塊將醃製__main__.ClassToPickle

而當你試圖加載醃製例如,它失敗,因爲它沒有找到該實例的類,這是__main__.ClassToPickle,而不是您在使用from ClassToPickle import ClassToPickle因爲這是最新進口ClassToPickle.ClassToPickle的一個。

修復程序會創建另一個腳本將處理傾銷,而不是做在ClassToPickle.py例如

import pickle 

from ClassToPickle import ClassToPickle 

if __name__=="__main__": 
    p = ClassToPickle(10) 
    pickle.dump(p, open('10.pickle', 'w')) 
+0

謝謝你的解釋!這一切對我來說都很有意義,而且你的腳本在控制檯和日食中都可以使用:) – fbessho

+0

@fbessho:很高興有幫助:) – mouad