OrderedDict
覆蓋__reduce__
,如果覆蓋__init__
或__new__
方法和/或要存儲其他屬性,則需要覆蓋它。
在你的情況,你所作出的參數爲__init__
強制(不強制對dict
或OrderedDict
),所以你需要重寫__reduce__
:
:
import collections
class OD(collections.OrderedDict):
def __init__(self, items):
super().__init__(items)
def __reduce__(self):
state = super().__reduce__()
# OrderedDict.__reduce__ returns a 5 tuple
# the first and last can be kept
# the fourth is None and needs to stay None
# the second must be set to an empty sequence
# the third can be used to store attributes
newstate = (state[0],
([],),
None,
None,
state[4])
return newstate
這現在可以毫無問題地酸菜
import pickle
a = OD((('a',1), ('b', 2)))
with open('test.pickle','wb') as fout:
pickle.dump(a, fout)
with open('test.pickle','rb') as fin:
pickle.load(fin)
但是,如果你想要在你的__init__
中未設置的屬性,這將無法正確工作:
a = OD((('a',1), ('b', 2)))
a.a = 10
with open('test.pickle','wb') as fout:
pickle.dump(a, fout)
with open('test.pickle','rb') as fin:
b = pickle.load(fin)
b.a # AttributeError: 'OD' object has no attribute 'a'
爲了做到這一點,您需要更改上述__reduce__
函數以返回第三個參數。例如,你可以簡單地返回__dict__
:
class OD(collections.OrderedDict):
def __init__(self, items):
super().__init__(items)
def __reduce__(self):
state = super().__reduce__()
newstate = (state[0],
([],),
self.__dict__,
None,
state[4])
return newstate
有了這個上面的例子可以正常工作。
很多設計取決於你希望你的子類的行爲。在某些情況下,最好通過第二個參數(傳遞給__init__
)傳遞項目。至於你如何設置你的屬性:有時足夠使用self.__dict__
,但在其他情況下,使用__setstate__
會更安全/更好。您一定要閱讀documentation of the pickle
module並檢查哪種方法最適合您。
我想我可能已經想出了一個解決方案,我認爲這可能對其他人有用。添加: – Tom