为你的酸洗使用二进制协议(而不是旧的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
>>>
正如你看到的,-1
协议(意为“最好,最快,最紧凑的协议”)工作得很好,而默认0
协议(旧的ASCII协议设计为兼容所有回到Python 1.5和更早的版本)给出了你所观察到的异常。
此外,-1
会更快和产生更紧凑的结果 - 你只需要确保你正确地保存和恢复二进制字符串它产生(因此,举例来说,如果你酸洗到文件,请务必打开后者wb
,而不是只是w
)。
如果由于某种原因,这个全能双赢的解决方案是不提供给你,有黑客和技巧(如子pickle.Pickler
,用你的子类的直接实例,而不是基地之一的pickle.dumps
确实,覆盖save
方法,以便在委托给超类之前跟踪type(obj)
),但升级到最新的最新协议(-1
保证在任何给定的Python版本中是版本支持的最高级版本)将是无论如何,如果可行的话,这是一个好主意。
http://stackoverflow.com/questions/2204155/why-am-i-我的班级定义插槽试图挑选 – 2017-01-16 15:33:37