如何使用自引用和带有插槽的类来挑选和取消对象?

Eri*_*got 8 python pickle slots

当此对象通过其中一个属性引用自身时,从带有插槽的类中拾取对象的正确方法是什么?这是一个简单的例子,我目前的实现,我不确定是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())
Run Code Online (Sandbox Code Playgroud)

例如,可以使用以下方法测试:

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)
Run Code Online (Sandbox Code Playgroud)

这是一个正确/可靠的实现吗?如果从一个类继承__getstate____setstate__应该怎么写?由于"循环"字典,内部是否存在内存泄漏?my_class__slots____setstate__

PEP 307中有一句话让我想知道酸洗my_class物体是否完全可行:

__getstate__方法应返回表示对象状态的可选值,而不引用对象本身.

这是否与对象本身的引用被腌制这一事实相冲突?

这是很多问题:任何评论,评论或建议都会非常感激!

Eri*_*got 5

它看起来像原始帖子建议的效果很好.

至于PEP 307的内容:

__getstate__方法应返回表示对象状态的可选值,而不引用对象本身.

我理解这只意味着该__getstate__方法必须返回一个不指向(不可解决的)原始对象的表示.因此,返回一个引用自身的对象就可以了,只要不引用原始(不可解决的)对象即可.