当此对象通过其中一个属性引用自身时,从带有插槽的类中挑选对象的正确方法是什么?这是一个简单的例子,我目前的实现,我不确定是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)
这是正确/强大的实施吗?如果__getstate__
继承自__setstate__
的班级,应如何撰写my_class
和__slots__
?由于“循环”字典,__setstate__
内是否存在内存泄漏?
PEP 307中有一句话让我想知道是否有可能以健壮的方式完成酸洗my_class
对象:
__getstate__
方法应返回表示对象状态的可选值,而不引用对象本身。
这是否与对象本身的引用被腌制这一事实相冲突?
这是很多问题:任何评论,评论或建议都会非常感激!
答案 0 :(得分:5)
看起来原帖的建议效果还不错。
关于PEP 307的内容:
__getstate__方法应返回表示对象状态的可选值,而不引用对象本身。
我理解这只意味着__getstate__
方法只需要返回一个不指向(不可推文)原始对象的表示。因此,返回一个引用自身的对象就可以了,只要没有引用原始(不可解决的)对象。