1

我将对象定义为A = Object()我指定类 Object() 的位置:通过我继续构造属性、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

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

4

2 回答 2

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的文档非常清楚地解决了这一点:

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

类似地,类是由命名引用腌制的,因此在 unpickling 环境中应用相同的限制。请注意,没有任何类的代码或数据被腌制

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

>>> A = Object
>>> del Object

如果您尝试 pickle Apickle模块将检查它是否可以访问该类。但是因为A.__name__Object找不到它并且无法腌制它。


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

同样,当类实例被腌制时,它们的类的代码和数据不会与它们一起被腌制。只有实例数据被腌制。这是有意完成的,因此您可以修复类中的错误或向类添加方法,并且仍然加载使用该类的早期版本创建的对象。如果您计划拥有可以看到多个版本的类的长期对象,则可能值得在对象中放置版本号,以便可以通过类的__setstate__()方法进行适当的转换。

于 2013-10-11T21:36:07.790 回答
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

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

于 2013-10-23T02:39:09.273 回答