Python pickle: Unclear "AttributeError: can't set attribute"

Python pickle: Unclear "AttributeError: can't set attribute"

在使用 pickle.load(...) 时,有可能引发 AttributeError: can't set attribute。然而,在更大的 pickle 文件上,这个错误根本没有帮助(因为我不知道是什么原因导致的)。

有什么方法可以获取更多信息或进行调试吗?如果有任何其他建议如何处理这个问题,我会很高兴听到他们!


错误最初来自 Jedi's 解析器分支。该问题是由 jedi.parser.fast 中的最新更改引起的。如果你想看到错误,你需要运行 python test/run.py on_import 100 两次。


编辑 - 原因:

>>> X.y = 3
>>> class X():
...  @property
...  def y(self): pass
... 
>>> X().y = 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

原因是这个 AttributeError 没有给你任何信息。将它与 __slots__ 的继承和继承对象 + pickle 中的属性结合起来,你会得到这个不清楚的错误。

我仍然认为这是 pickle 的错。我打算让这个问题悬而未决,因为我还没有找到正确调试它的方法。 Pickle 应该接受 AttributeError 并修改它。

dilldill.detect 中有 pickle 调试工具。我看不到你想调试什么对象,因为你上面的代码不是由于 pickle… 但无论如何我可以在下面展示一个例子。

>>> class Test(object):
...   def __init__(self, x, y):
...     self.x = x
...     self.y = y
... 
>>> x = (i for i in range(10))
>>> y = iter(range(10))
>>> 
>>> t = Test(x,y)
>>> 
>>> import dill
>>> dill.detect.errors(t)
PicklingError("Can't pickle <type 'listiterator'>: it's not found as __builtin__.listiterator",)
>>> dill.detect.badobjects(t) 
<__main__.Test object at 0x1086970d0>
>>> dill.detect.badobjects(t, 1)
{'__hash__': <method-wrapper '__hash__' of Test object at 0x1086970d0>, '__setattr__': <method-wrapper '__setattr__' of Test object at 0x1086970d0>, '__reduce_ex__': <built-in method __reduce_ex__ of Test object at 0x1086970d0>, 'y': <listiterator object at 0x108890d50>, '__reduce__': <built-in method __reduce__ of Test object at 0x1086970d0>, '__str__': <method-wrapper '__str__' of Test object at 0x1086970d0>, '__format__': <built-in method __format__ of Test object at 0x1086970d0>, '__getattribute__': <method-wrapper '__getattribute__' of Test object at 0x1086970d0>, '__delattr__': <method-wrapper '__delattr__' of Test object at 0x1086970d0>, '__repr__': <method-wrapper '__repr__' of Test object at 0x1086970d0>, '__dict__': {'y': <listiterator object at 0x108890d50>, 'x': <generator object <genexpr> at 0x108671f50>}, 'x': <generator object <genexpr> at 0x108671f50>, '__sizeof__': <built-in method __sizeof__ of Test object at 0x1086970d0>, '__init__': <bound method Test.__init__ of <__main__.Test object at 0x1086970d0>>}
>>> dill.detect.trace(True)
>>> dill.dumps(t)
T2: <class '__main__.Test'>
F2: <function _create_type at 0x10945c410>
T1: <type 'type'>
F2: <function _load_type at 0x10945c398>
T1: <type 'object'>
D2: <dict object at 0x10948b7f8>
F1: <function __init__ at 0x108894938>
F2: <function _create_function at 0x10945c488>
Co: <code object __init__ at 0x108873830, file "<stdin>", line 2>
F2: <function _unmarshal at 0x10945c320>
D1: <dict object at 0x1085b9168>
D2: <dict object at 0x10947e910>
D2: <dict object at 0x108898910>
T4: <type 'listiterator'>
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
#...snip...
pickle.PicklingError: Can't pickle <type 'listiterator'>: it's not found as __builtin__.listiterator
>>>

我想不出 AssertionError 来自 pickle.dump 的情况...但是上面的调试工具应该以完全相同的方式工作案例.

如果您 post 一个简单的可重现对象(即最好是标准库)在酸洗时产生 AttributeError,我将更新我的示例。