類型通過定義一個或多個(相當大)的一組方法來定義它的實例如何被清理。每個人都有自己的微妙行爲。見the docs on the pickle protocol。在collections.defaultdict
的情況下,它使用__reduce__
方法:
>>> l = collections.defaultdict(list)
>>> l.__reduce__()
(<type 'collections.defaultdict'>, (<type 'list'>,), None, None, <dictionary-itemiterator object at 0x7f031fb3c470>)
在元組中的第一項有類型,並且第二項是自變量的元組實例化時傳遞到的類型。如果您不覆蓋__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
這只是粗略的例子,因爲有更多的酸洗(如__reduce_ex__
),這一切都相當複雜。在這種情況下,使用__getinitargs__
可能會更方便。
或者,你可以讓你的類的__init__
方法採取可選調用,默認爲list
,或者你可以只用而不是類的函數:
def listdict():
return collections.defaultdict(list)
您使用'pickle'或' cpickle'? – aaronasterling 2010-10-04 13:10:22
我正在使用'cPickle'。 – 2010-10-04 13:10:48