【问题标题】:Python pickle: Unclear "AttributeError: can't set attribute"Python pickle:不清楚“AttributeError:无法设置属性”
【发布时间】:2015-02-01 19:22:57
【问题描述】:

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

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


错误最初来自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 应该接受 AttributeError 并修改它。

【问题讨论】:

    标签: python python-2.7 python-3.x pickle


    【解决方案1】:

    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
    >>>
    

    我想不出有一个 AssertionErrorpickle.dump 从我的头顶冒出来的情况......但上述调试工具在这种情况下应该以完全相同的方式工作。

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

    【讨论】:

    • 不错。我一直在寻找这样的东西 :-) 不过,我认为缺少标准库。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-17
    • 2015-02-08
    • 2014-08-09
    • 2018-08-30
    • 2022-07-17
    • 2014-04-06
    • 1970-01-01
    相关资源
    最近更新 更多