當這個對象通過它的一個屬性引用自己時,什麼是從帶有插槽的類中pickle一個對象的正確方法?下面是一個簡單的例子,我目前的實現,我不知道是100%正確的:如何使用自引用和帶有插槽的類來醃製和取消對象?
import weakref
import pickle
class my_class(object):
__slots__ = ('an_int', 'ref_to_self', '__weakref__')
def __init__(self):
self.an_int = 42
self.ref_to_self = weakref.WeakKeyDictionary({self: 1})
# How to best write __getstate__ and __setstate__?
def __getstate__(self):
obj_slot_values = dict((k, getattr(self, k)) for k in self.__slots__)
# Conversion to a usual dictionary:
obj_slot_values['ref_to_self'] = dict(obj_slot_values['ref_to_self'])
# Unpicklable weakref object:
del obj_slot_values['__weakref__']
return obj_slot_values
def __setstate__(self, data_dict):
# print data_dict
for (name, value) in data_dict.iteritems():
setattr(self, name, value)
# Conversion of the dict back to a WeakKeyDictionary:
self.ref_to_self = weakref.WeakKeyDictionary(
self.ref_to_self.iteritems())
這例如可以與測試:
def test_pickling(obj):
"Pickles obj and unpickles it. Returns the unpickled object"
obj_pickled = pickle.dumps(obj)
obj_unpickled = pickle.loads(obj_pickled)
# Self-references should be kept:
print "OK?", obj_unpickled == obj_unpickled.ref_to_self.keys()[0]
print "OK?", isinstance(obj_unpickled.ref_to_self,
weakref.WeakKeyDictionary)
return obj_unpickled
if __name__ == '__main__':
obj = my_class()
obj_unpickled = test_pickling(obj)
obj_unpickled2 = test_pickling(obj_unpickled)
這是一個正確的/健壯實施?如果my_class
繼承自__slots__
的類,應如何編寫__getstate__
和__setstate__
? __setstate__
由於「循環」字典有內存泄漏嗎?
有在PEP 307了一句話,讓我懷疑是否酸洗my_class
對象是一個穩健的方式在所有可能的:
的
__getstate__
方法應返回表示對象的狀態picklable值,而不參照對象本身。
這是否與對象本身的引用被醃漬的事實相沖突?
這是很多問題:任何評論,評論或建議將不勝感激!
如果您希望my_class是可分類的,請確保將self .__ slots__替換爲類似於:slots = set();對於cls in self .__ class __。mro():slots.update(getattr(cls,'__slots__',())) – 2015-08-22 00:57:10
關閉我的頭頂,我會說這個子類更新'self .__ slots__',所以我猜子類化實際上沒有問題,對吧? – EOL 2015-08-22 01:08:35
不是。他們沒有。 :-)想象出來需要一些時間,因此評論。 :-) – 2015-08-22 01:23:52