fbe*_*sho 7 python namespaces pickle
当我使用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'))
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程序?
请帮我.
那是因为__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)