由class定义的对象的pickle.dump错误

时间:2013-10-11 20:27:23

标签: python pickle

我将对象定义为A = Object(),其中我指定了类Object():pass 我继续构建属性,A.b,A.c等。大多数是列表,其中一些项目是列表。我写道:

  outFile = file('A.obj','wb')
  pickle.dump(A,outFile)
  outFile.close()

我收到了错误:

PicklingError: Can't pickle <class '__main__.Object'>: it's not found as __main__.Object

我的目标是能够转储(以后加载)对象。

2 个答案:

答案 0 :(得分:1)

错误很明显。你做了类似(或相当于)以下的事情:

>>> import pickle
>>> class Object(object): pass
... 
>>> A = Object
>>> del Object
>>> pickle.dumps(A)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/pickle.py", line 1374, in dumps
    Pickler(file, protocol).dump(obj)
  File "/usr/lib/python2.7/pickle.py", line 224, in dump
    self.save(obj)
  File "/usr/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.7/pickle.py", line 748, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <class '__main__.Object'>: it's not found as __main__.Object

pickle的文档很清楚地解决了这个问题:

  

请注意,函数(内置和用户定义)被“完全”腌制   合格的“名称参考,而不是价值。这意味着只有   功能名称被腌制,以及模块的名称   功能在中定义。既不是函数的代码,也不是它的任何代码   功能属性是pickle。因此必须是定义模块   可以在unpickling环境中导入,并且模块必须包含   命名对象,否则将引发异常。

     

同样,类通过命名引用进行pickle,所以相同   适用于unpickling环境的限制。请注意无   该类的代码或数据被腌制

因此,类的名称必须在酸洗/去除时才可用。 做完之后:

>>> A = Object
>>> del Object

如果您尝试挑选Apickle模块将检查它是否可以访问该类。但由于A.__name__Object,因此无法找到它并且无法腌制它。


请注意,这同样适用于用户定义的类的实例:

  

类似地,当类实例被腌制时,它们的类的代码和   数据不与它们一起腌制。只有实例数据   酸洗即可。这是故意完成的,因此您可以修复类中的错误   向类添加方法并仍然加载使用它创建的对象   该类的早期版本。如果你打算长寿   看到很多版本的类的对象,可能是值得的   在对象中放置版本号以便进行适当的转换   可以通过班级的__setstate__()方法制作。

答案 1 :(得分:0)

所以...说你正在建造这样的东西...... 它在工厂方法中构建类的实例。 然后你会收到你报告的错误。回顾一下追溯...... pickle试图做的是使用pickle.save_global来序列化你的类。在函数内部构建,但在__main__中,类实际上被命名为__main___.Object ...并且没有__main__.Object类......它嵌套在object_factory内命名空间。在python中,工厂方法被用于动态构建类,实例,函数和其他对象。如果你使用的是工厂方法,你可以在另一个而不是函数中构建一个工厂方法......并且你有一个更好的机会让一个pickler能够序列化你的实例Object类比你现在做的。

>>> def object_factory(a,b):
...   c = a+b
...   class Object(object):
...     d = 1
...     e = [c, d, [1,2,3]]
...     def foo(self, x):
...       return (self.d * c) + (x * Object.e)
...   return Object()
... 
>>> A = object_factory([4,5],[6,7])
>>> A
<__main__.Object object at 0x973030>
>>> A.d
1
>>> A.e
[[4, 5, 6, 7], 1, [1, 2, 3]]
>>> A.foo(1)
[4, 5, 6, 7, [4, 5, 6, 7], 1, [1, 2, 3]]
>>> 
>>> _A = pickle.dumps(A)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 1366, in dumps
    Pickler(file, protocol).dump(obj)
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 224, in dump
    self.save(obj)
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 401, in save_reduce
    save(args)
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 562, in save_tuple
    save(element)
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 753, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <class '__main__.Object'>: it's not the same object as __main__.Object

发布您的代码会有所帮助,或至少有一些玩具代码可以证明您的问题。