当我将pickle与unittest一起使用时,出现错误。
我写了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程序来制作 pickle 文件。
然后,当我单独运行程序文件#2时(即输入“python SomeClass.py”),它可以工作。
而且,当我单独运行程序#3(即输入“python SomeClassTest.py”)时,它也可以工作。
但是,当我在eclipse + pydev中将程序#3作为“单元测试”运行时,它在下面返回一条错误消息。
而且,当我注释掉导入ClassToPickle类的行(程序#3的第3行,并注释为“REQUIRED_LINE”)时,该行不起作用并返回以下错误消息。
我想问题是关于python中的 namespace 的,但是我不知道到底发生了什么,以及如何解决它。
如何“以单元测试(在eclipse + pydev中)运行”#3程序,
并在命令行中运行#3程序,而无需导入ClassToPickle的行?
请帮我。
最佳答案
那是因为__main__.ClassToPickle != ClassToPickle.ClassToPickle
,所以这样想:
当您在ClassToPickle.py
脚本中 pickle ClassToPickle的类实例时,pickle模块将 pickle 对该类的所有引用,这意味着它将 pickle 定义该类的模块名称,并且由于您执行了脚本ClassToPickle.py
,这意味着该模块将被设置为__main__
,这意味着pickle
模块将 pickle __main__.ClassToPickle
。
当您尝试加载已 pickle 的实例时,它失败了,因为它找不到实例的类__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'))