2013-10-11 42 views
0

我有对象定义为A = Object()其中我指定类对象。我写道:pickle.dump错误的类定义的对象

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 

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

回答

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的文档很明确阐述:

Note that functions (built-in and user-defined) are pickled by “fully qualified” name reference, not by value. This means that only the function name is pickled, along with the name of the module the function is defined in. Neither the function’s code, nor any of its function attributes are pickled. Thus the defining module must be importable in the unpickling environment, and the module must contain the named object, otherwise an exception will be raised.

Similarly, classes are pickled by named reference, so the same restrictions in the unpickling environment apply. Note that none of the class’s code or data is pickled

因此,的名称,该类必须是酸洗/取出时可用。 后做:

>>> A = Object 
>>> del Object 

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


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

Similarly, when class instances are pickled, their class’s code and data are not pickled along with them. Only the instance data are pickled. This is done on purpose, so you can fix bugs in a class or add methods to the class and still load objects that were created with an earlier version of the class. If you plan to have long-lived objects that will see many versions of a class, it may be worthwhile to put a version number in the objects so that suitable conversions can be made by the class’s __setstate__() method.

+1

或者他可能已经定义了一个函数而不是顶层的函数。与删除类相比,这是一个比较常见的问题(并且难以修复,除非全局类变得有意义 - 您必须使用自定义酸洗来定义代理类 – abarnert

0

所以...说你正在构建这样的事情... 它建立一个类的实例里面工厂方法。 然后你会得到你报告的错误。看看追溯...咸菜想要做的是使用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 

这将有助于您的代码发布,或至少一些玩具代码,演示您的问题。

相关问题