繁体   English   中英

类定义的对象的pickle.dump错误

[英]pickle.dump error for object defined by class

我有一个定义为A = Object() ,其中我指定了Object()类:pass我着手构造属性,Ab,Ac等。大多数是列表,其中一些项是列表。 我写:

  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

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

错误非常明显。 您做了类似(或等同于)以下操作:

>>> 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的文档很清楚地解决了这一问题:

请注意, 函数(内置的和用户定义的)是由“完全限定”的名称引用而不是由value腌制的 这意味着仅对函数名称以及在中定义函数的模块名称进行了酸洗 该函数的代码或其任何函数属性都不会被腌制。 因此,定义模块必须在解酸环境中是可导入的,并且该模块必须包含命名对象,否则将引发异常。

同样,通过命名引用对类进行酸洗 ,因此在未酸洗环境中也适用相同的限制。 请注意, 该类的代码或数据都不会被腌制

因此,在酸洗/酸洗时,该类的名称 必须可用。 完成后:

>>> A = Object
>>> del Object

如果您尝试使A腌制,则pickle模块将检查它是否可以访问该类。 但是由于A.__name__Object它无法找到它并且也无法使它腌制。


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

同样, 当对类实例进行腌制时,其类的代码和数据也不会与其一起被腌制。 仅实例数据被腌制 这样做是有目的的,因此您可以修复类中的错误或向类中添加方法,并仍然加载使用该类的早期版本创建的对象。 如果计划使用寿命很长的对象,而该对象将看到类的许多版本,则可能值得在对象中放入版本号,以便可以通过类的__setstate__()方法进行适当的转换。

所以...说您正在构建类似这样的东西...它将在工厂方法内构建类的实例。 然后,您将得到报告的错误。 看一下追溯... pickle想要做的是使用pickle.save_global来序列化您的类。 内置在函数内部,但是在__main__ ,该类实际上被命名为__main___.Object ...,并且没有__main__.Object类...它嵌套在object_factory命名空间内。 在python中,factory方法用于动态构建类,实例,函数和其他对象。 如果您使用的是工厂方法,则可以在另一个而不是函数中构建工厂方法……与现在相比,您有更大的机会让选择器能够序列化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

发布您的代码或至少展示一些问题的玩具代码会有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM