本文介绍了python pickle上的命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将咸菜与unittest一起使用时出现错误.

I got an error when I use pickle with unittest.

我编写了3个程序文件:

I wrote 3 program files:

  1. 要腌制一堂课,
  2. 对于在#1中使用类的类,
  3. 在#2中测试类的单元测试.

和真实代码分别如下.

#1. ClassToPickle.py

#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

#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

#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(即输入"python SomeClassTest.py")时,它也可以工作.

I ran #1 program first to make pickle file.
And then, when I run program file #2 alone (i.e. enter "python SomeClass.py"), it works.
And, when I run program #3 alone (i.e. enter "python SomeClassTest.py"), it also works.

但是,当我在eclipse + pydev中将程序#3作为单元测试"运行时,它会在下面返回错误消息.

However, when I run program #3 as "unit-test" in eclipse+pydev, it returns an error message below.

而且,当我注释掉导入ClassToPickle类的行(程序#3的第3行,并注释为"REQUIRED_LINE")时,它不起作用并返回以下错误消息.

And also, when I commented out a line that import ClassToPickle class (line 3 in program #3 and commented as "REQUIRED_LINE"), It doesn't work and return an error message described below.

我想问题出在python中的命名空间,但是我不知道到底发生了什么,该怎么办.

I guess the problem is about namespace in python, but I don't know what happened exactly and what can I do for resolving it.

如何正确地作为单元测试运行(在eclipse + pydev中)"#3程序,
并在命令行中运行#3程序,而无需导入ClassToPickle的行?
请帮助我.

How can I "run as unit-test (in eclipse+pydev)" #3 program correctly,
and run #3 program in command line without the line which imports ClassToPickle?
Please help me.

推荐答案

那是因为__main__.ClassToPickle != ClassToPickle.ClassToPickle,这样想吧:

当您在ClassToPickle.py脚本中腌制ClassToPickle的类实例时,pickle模块将腌制对该类的所有引用,这意味着它将腌制定义该类的模块名称,并且因为您执行了脚本ClassToPickle.py表示将模块设置为__main__,这表示pickle模块将腌制__main__.ClassToPickle.

When you pickled the class instance of ClassToPickle in the ClassToPickle.py script, the pickle module will pickle all the reference to the class which mean it will pickle the module name where the class was defined, and because you executed the script ClassToPickle.py this mean that the module will be set to __main__ which mean that pickle module will pickle __main__.ClassToPickle.

当您尝试加载已腌制的实例时,它失败了,因为它找不到该实例的类是__main__.ClassToPickle,而不是您使用from ClassToPickle import ClassToPickle导入的那个类,因为最新的是ClassToPickle.ClassToPickle.

And when you tried to load the pickled instance it fail because it didn't find the instance's class which is __main__.ClassToPickle and not the one that you imported using from ClassToPickle import ClassToPickle because this latest is ClassToPickle.ClassToPickle.

一个解决方法是创建另一个脚本来处理转储,而不是在ClassToPickle.py中进行

A fix will be to create another script that will handle dumping instead of doing it in ClassToPickle.py e.g.

import pickle

from ClassToPickle import ClassToPickle

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

这篇关于python pickle上的命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 05:43