首页 文章

python pickle上的命名空间

提问于
浏览
6

当我使用pickle和unittest时出错了 .

我写了3个程序文件:

  • 对于要腌制的类,

  • 对于在#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作为“单元测试”运行时,它会在下面返回一条错误消息 .

================================================= =====================错误:testA(SomeClassTest.SomeClassTest)--------------------- - - - - - - - - - - - - - - - - - - - - - - - - - 追溯(最近一次调用最后一次):$ file“/home/tmp/pickle_problem/SomeClassTest.py”,第9行,在testA中sc = SomeClass()$ File“/home/tmp/pickle_problem/SomeClass.py”,第8行,在init self.pickle = pickle.load(open(“10.pickle”,“r”))$ File“/usr/lib/python2.7/pickle.py”,第1378行,在加载返回Unpickler(文件) .load()$ File“/usr/lib/python2.7/pickle.py”,第858行,在load dispatchkey文件“/usr/lib/python2.7/pickle.py”,第1090行,在load_global klass = self.find_class(module,name)$ file“/usr/lib/python2.7/pickle.py”,第1126行,在find_class中klass = getattr(mod,name)$ AttributeError:'module'对象没有属性'ClassToPickle '------------------------------------------------- ---------------------在0.002s中进行1次测试失败(错误= 1)

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

E ================================================ ======================错误:testA(main.SomeClassTest)-------------------- --------------------------------------------------回溯(最近调用最后一次):文件“SomeClassTest.py”,第9行,在testA中sc = SomeClass()文件“/home/tmp/pickle_problem/SomeClass.py”,第8行,在init self.pickle = pickle中 . load(open(“10.pickle”,'r'))文件“/usr/lib/python2.7/pickle.py”,第1378行,在加载返回Unpickler(文件).load()文件“/ usr / lib / python2.7 / pickle.py“,第858行,在load dispatchkey文件”/usr/lib/python2.7/pickle.py“,第1090行,在load_global中klass = self.find_class(module,name)File” /usr/lib/python2.7/pickle.py“,第1126行,在find_class中klass = getattr(mod,name)AttributeError:'module'对象没有属性'ClassToPickle'----------- -------------------------------------------------- ---------在0.001秒内完成1次测试失败(错误= 1)

我想问题是关于python中的命名空间,但我不知道究竟发生了什么,我该怎么做才能解决它 .

我怎样才能正确编程#1272695_#3
并在命令行中运行#3程序而没有导入ClassToPickle的行?
请帮我 .

1 回答

  • 7

    因为 __main__.ClassToPickle != ClassToPickle.ClassToPickle ,想到这样:

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

    当你试图加载pickle实例时,它失败了,因为它没有't find the instance'的类 __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'))
    

相关问题