Dar*_*zer 28 python pickle slots
我正在尝试挑选我定义的(新式)类的对象.但是我收到以下错误:
>>> with open('temp/connection.pickle','w') as f:
... pickle.dump(c,f)
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "/usr/lib/python2.5/pickle.py", line 1362, in dump
Pickler(file, protocol).dump(obj)
File "/usr/lib/python2.5/pickle.py", line 224, in dump
self.save(obj)
File "/usr/lib/python2.5/pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "/usr/lib/python2.5/pickle.py", line 419, in save_reduce
save(state)
File "/usr/lib/python2.5/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/usr/lib/python2.5/pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "/usr/lib/python2.5/pickle.py", line 663, in _batch_setitems
save(v)
File "/usr/lib/python2.5/pickle.py", line 306, in save
rv = reduce(self.proto)
File "/usr/lib/python2.5/copy_reg.py", line 76, 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)
我没有__slots__在班上明确定义.我做了什么隐含地定义它?我该如何解决这个问题?我需要定义__getstate__吗?
更新: gnibbler选择了一个很好的例子.我试图挑选的对象的类包装了一个套接字.(现在发生在我身上)套接字定义__slots__并没有__getstate__充分的理由.我假设一旦进程结束,另一个进程就无法解开并使用前一进程的套接字连接.因此,虽然我接受Alex Martelli的优秀答案,但我将不得不采取不同的策略,而不是挑选"分享"对象参考.
Ale*_*lli 31
定义__slots__(而不是__getstate__)的类可以是您的祖先类,也可以是您的属性或项的类(或祖先类),直接或间接:实质上,有向图的引用图中的任何对象的类你的对象是root用户,因为pickling需要保存整个图形.
您的困境的一个简单解决方案是使用协议-1,这意味着"最好的协议泡菜可以使用"; 默认是一个古老的基于ASCII的协议,它对__slots__vs 强加了这个限制__getstate__.考虑:
>>> class sic(object):
... __slots__ = 'a', 'b'
...
>>> import pickle
>>> pickle.dumps(sic(), -1)
'\x80\x02c__main__\nsic\nq\x00)\x81q\x01.'
>>> pickle.dumps(sic())
Traceback (most recent call last):
[snip snip]
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采用了__slots__大步,而默认协议提供了您所看到的相同异常.
协议的问题-1:它产生二进制字符串/文件,而不是像默认协议那样的ASCII字符串/文件; 足够古老的Python版本无法加载生成的pickle文件.除了关键的一个优点之外,优点还__slots__包括更紧凑的结果和更好的性能.
如果您被迫使用默认协议,那么您需要确切地确定哪个类给您带来麻烦以及确切原因.如果是这种情况,我们可以讨论策略(但是如果你可以使用-1协议,那就更好了,不值得讨论;-)和简单的代码检查寻找麻烦的类/对象证明太复杂了(我在记住一些基于深度复制的技巧,以获得整个图形的可用表示,以防你想知道).
也许您的实例的属性正在使用 __slots__
例如,socket已经__slots__所以它不能被酸洗
您需要确定导致错误的属性并编写自己的
属性__getstate__并__setstate__忽略该属性
| 归档时间: |
|
| 查看次数: |
10650 次 |
| 最近记录: |