当我将pickle与unittest一起使用时,出现错误。

我写了3个程序文件:

  • 用于 pickle 一类,
  • 用于使用#1中的类的类
  • unittest用于测试#2中的类。

  • 实码分别如下。

    #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'))
    

    10-06 10:38