2011-10-28 32 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