代码之家  ›  专栏  ›  技术社区  ›  Eric O. Lebigot

如何用自引用和从带有槽的类中pickle和unpickle对象?

  •  7
  • Eric O. Lebigot  · 技术社区  · 15 年前

    当这个对象通过它的一个属性引用自己时,从带有槽的类中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)
    

    这是正确/可靠的实现吗?该如何 __getstate__ __setstate__ 写成 my_class 从类继承 __slots__ ?里面有内存泄漏吗 α-塞特他汀 因为“循环”口述?

    有句话在 PEP 307 这让我想知道是不是腌制 米亚尔 对象以一种健壮的方式是完全可能的:

    这个 γ-GETSteste* 方法应返回表示对象状态的可选取值,而不引用对象本身。

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

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

    1 回复  |  直到 11 年前
        1
  •  5
  •   Eric O. Lebigot    11 年前

    看起来原帖建议的效果很好。

    至于PEP 307的内容:

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

    我明白这只意味着 __getstate__ 方法只需返回一个不指向(不可拾取)原始对象的表示。因此,返回引用自身的对象是很好的,只要没有引用原始(不可拾取)对象。