Python酸洗槽错误

Cer*_*rin 11 python pickle

我有一个很大的实例,我一直在酸洗,但最近我尝试转储它时开始收到此错误:

  File "/usr/lib/python2.6/copy_reg.py", line 77, in _reduce_ex
    raise TypeError("a class that defines __slots__ without "
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled
Run Code Online (Sandbox Code Playgroud)

我不明白这个错误,因为我的所有类似乎都定义了一个__getstate__方法,似乎没有定义__slots__.我无法隔离更改我触发了这个错误.

我只能假设我的实例中有一些嵌套在深层的对象导致了这种情况.有没有办法获得更多信息?如何找到触发此错误的确切对象的类?

Ale*_*lli 13

使用二进制协议进行酸洗(而不是你似乎默认使用的旧ASCII),你会没事的.注意:

>>> class ws(object):
...   __slots__ = 'a', 'b'
...   def __init__(self, a=23, b=45): self.a, self.b = a, b
... 
>>> x = ws()
>>> import pickle
>>> pickle.dumps(x, -1)
'\x80\x02c__main__\nws\nq\x00)\x81q\x01N}q\x02(U\x01aq\x03K\x17U\x01bq\x04K-u\x86q\x05b.'
>>> pickle.dumps(x)
Traceback (most recent call last):
    [[snip]]
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/copy_reg.py", line 77, in _reduce_ex
    raise TypeError("a class that defines __slots__ without "
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled
>>> 
Run Code Online (Sandbox Code Playgroud)

如你所见,-1协议(意思是"最好,最快,最紧凑的协议")工作得很好,而默认0协议(旧的ascii协议设计为兼容Python 1.5及更早版本)完全给出了你观察到的异常.

此外,它-1会更快产生更紧凑的结果 - 你只需要确保你正确地保存和恢复它产生的二进制字符串(例如,如果你正在腌制文件,请务必打开后者wb,不要只是w).

如果出于某种原因,你无法使用这种全能解决方案,那么就有黑客和技巧(例如,子类pickle.Pickler,直接使用子类的实例而不是基类的实例)pickle.dumps,覆盖save方法以便跟踪type(obj)之前的方法委托给超类),但升级到正确的,最新的协议(-1保证在任何给定的Python版本上,是版本支持的最先进的协议)无论如何都是个好主意,如果可行的话.