python pickle上的命名空间

fbe*_*sho 7 python namespaces pickle

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

我写了3个程序文件:

  1. 对于要被腌制的课程,
  2. 对于在#1中使用类的类,
  3. 用于测试#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'))
Run Code Online (Sandbox Code Playgroud)

#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()
Run Code Online (Sandbox Code Playgroud)

#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()
Run Code Online (Sandbox Code Playgroud)

我先运行#1程序制作pickle文件.
然后,当我单独运行程序文件#2(即输入"python SomeClass.py")时,它可以工作.
而且,当我单独运行程序#3(即输入"python SomeClassTest.py")时,它也可以工作.

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

================================================== ====================
错误:testA(SomeClassTest.SomeClassTest)
---------------------- ------------------------------------------------
Traceback(最近一次调用last):
$ 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'

-------------------------------------------------- --------------------
跑掉1测试0.002秒

FAILED(错误= 1)

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

E
================================================= =====================
错误:testA( .SomeClassTest)
--------------------- -------------------------------------------------
Traceback (最近一次调用最后一次):
文件"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.001s

失败1测试失败(错误= 1)

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

我如何"正确地运行单元测试(在eclipse + pydev中)"#3程序,
并在没有导入ClassToPickle的行的情况下在命令行中运行#3程序?
请帮我.

mou*_*uad 9

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

当您在ClassToPickle.py脚本中腌制ClassToPickle的类实例时,pickle模块将挑选对该类的所有引用,这意味着它将挑选定义类的模块名称,并且因为您执行了脚本,ClassToPickle.py这意味着该模块将是设置__main__为该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'))
Run Code Online (Sandbox Code Playgroud)