我有一个继承自defaultdict这样的类:
class listdict(defaultdict):
def __init__(self):
defaultdict.__init__(self, list)
Run Code Online (Sandbox Code Playgroud)
我可以腌制它,但当我取消它时,会发生这种情况:
('__init__() takes exactly 1 argument (2 given)', <class 'listdict'>, (<type 'list'>,))
Run Code Online (Sandbox Code Playgroud)
该类没有定义pickle协议的任何特殊方法.正常的酸洗和去除defaultdict(list)工作按预期工作.任何人都可以开导我吗?
类型通过定义一组(相当大)的方法来定义它的实例如何被腌制.每个都有自己的微妙行为.查看pickle协议的文档.在这种情况下collections.defaultdict,它使用的__reduce__方法:
>>> l = collections.defaultdict(list)
>>> l.__reduce__()
(<type 'collections.defaultdict'>, (<type 'list'>,), None, None, <dictionary-itemiterator object at 0x7f031fb3c470>)
Run Code Online (Sandbox Code Playgroud)
元组中的第一项是类型,第二项是在实例化时传递给类型的参数元组.如果不覆盖__reduce__,第一项将正确更改为您的类型,但第二项不会.这会导致您看到的错误.如何修复它的粗略示例:
>>> import collections
>>> import pickle
>>> class C(collections.defaultdict):
... def __init__(self):
... collections.defaultdict.__init__(self, list)
... def __reduce__(self):
... t = collections.defaultdict.__reduce__(self)
... return (t[0], ()) + t[2:]
...
>>> c = C()
>>> c[1].append(2)
>>> c[2].append(3)
>>> c2 = pickle.loads(pickle.dumps(c))
>>> c2 == c
True
Run Code Online (Sandbox Code Playgroud)
这只是一个粗略的例子,因为更多的是酸洗(比如__reduce_ex__),而且这一切都相当错综复杂.在这种情况下,使用__getinitargs__可能更方便.
或者,您可以使您的类的__init__方法采用可选的可调用,默认为list,或者您可以只使用函数而不是类:
def listdict():
return collections.defaultdict(list)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4068 次 |
| 最近记录: |