python pickle 上的命名空间
Posted
技术标签:
【中文标题】python pickle 上的命名空间【英文标题】:namespace on python pickle 【发布时间】:2011-12-17 05:25:03 【问题描述】:当我将 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 程序来制作泡菜文件。 然后,当我单独运行程序文件 #2 时(即输入“python SomeClass.py”),它就可以工作了。 而且,当我单独运行程序 #3(即输入“python SomeClassTest.py”)时,它也可以工作。
但是,当我在 eclipse+pydev 中将程序 #3 作为“单元测试”运行时,它会返回以下错误消息。
================================================ ======================== 错误:testA (SomeClassTest.SomeClassTest) -------------------------------------------------- -------------------- Traceback(最近一次调用最后一次):$ 文件 “/home/tmp/pickle_problem/SomeClassTest.py”,第 9 行,在 测试A sc = SomeClass()$ 文件“/home/tmp/pickle_problem/SomeClass.py”,第 8 行,在 初始化 self.pickle = pickle.load(open("10.pickle", 'r'))$ 文件“/usr/lib/python2.7/pickle.py”,第 1378 行,加载中 返回 Unpickler(file).load()$ 文件“/usr/lib/python2.7/pickle.py”,第 858 行,加载中 dispatchkey 文件“/usr/lib/python2.7/pickle.py”,第 1090 行,在 load_global klass = self.find_class(module, name)$ 文件“/usr/lib/python2.7/pickle.py”,第 1126 行,在 find_class klass = getattr(mod, name)$ AttributeError: 'module' 对象没有属性 'ClassToPickle' -------------------------------------------------- -------------------- 在 0.002 秒内运行 1 次测试 FAILED (errors=1)
而且,当我注释掉导入 ClassToPickle 类的行(程序 #3 中的第 3 行并注释为“REQUIRED_LINE”)时,它不起作用并返回如下所述的错误消息。
电子 ==================================================== ===================== 错误:testA (main.SomeClassTest) -------------------------------------------------- -------------------- 回溯(最近一次通话最后一次): 文件“SomeClassTest.py”,第 9 行,在 testA sc = SomeClass()init 中的文件“/home/tmp/pickle_problem/SomeClass.py”,第 8 行 self.pickle = pickle.load(open("10.pickle", 'r')) 文件“/usr/lib/python2.7/pickle.py”,第 1378 行,加载中 返回 Unpickler(file).load() 文件“/usr/lib/python2.7/pickle.py”,第 858 行,加载中 调度键 文件“/usr/lib/python2.7/pickle.py”,第 1090 行,在 load_global klass = self.find_class(模块,名称) 文件“/usr/lib/python2.7/pickle.py”,第 1126 行,在 find_class klass = getattr(mod, name) AttributeError:“模块”对象没有属性“ClassToPickle” -------------------------------------------------- -------------------- 在 0.001 秒内运行 1 次测试 失败(错误=1)
我猜这个问题是关于 python 中的命名空间,但我不知道到底发生了什么以及我能做些什么来解决它。
如何正确“作为单元测试运行(在 eclipse+pydev 中)”#3 程序, 并在没有导入 ClassToPickle 的行的命令行中运行 #3 程序? 请帮帮我。
【问题讨论】:
是否有另一个ClassToPickle.py
文件可以找到,而不是您在此处显示的文件?
@ThomasK 感谢您的评论,但答案是否定的。目录中只有三个此处显示的 .py 文件,而且我从未创建名为 ClassToPickle.py
的文件。
【参考方案1】:
那是因为__main__.ClassToPickle != ClassToPickle.ClassToPickle
,这样想:
当您在ClassToPickle.py
脚本中腌制 ClassToPickle 的类实例时,腌制模块将腌制对该类的所有引用,这意味着它将腌制定义该类的模块名称,并且因为您执行了脚本@ 987654323@ 这意味着模块将被设置为__main__
这意味着pickle
模块将腌制__main__.ClassToPickle
。
当您尝试加载腌制实例时它失败了,因为它没有找到实例的类 __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'))
【讨论】:
感谢您的解释!这一切对我来说都很有意义,你的脚本在控制台和 Eclipse 中都可以工作:) @fbessho:很高兴有帮助 :)以上是关于python pickle 上的命名空间的主要内容,如果未能解决你的问题,请参考以下文章