Python酸洗保持对象身份 [英] Python pickling keep object identity

查看:74
本文介绍了Python酸洗保持对象身份的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有任何方法可以保留腌制对象的身份,即具有以下打印内容True:

Is there any way to preserve the identity of a pickled object, i.e. have the below print True:

import pickle

class Foo:
    pass

x = Foo()
print(x is pickle.loads(pickle.dumps(x)))          #False

我在Linux机器上使用cPickle和cpython 3.x,不需要便携式的东西.

I am using cPickle and cpython 3.x on a Linux box, don't need something that's portable.

推荐答案

是的,这是可能的;您需要以某种方式在腌制结果中包括身份";在这种情况下,最自然的方法是使用__getnewargs__并使用__new__方法返回现有的缓存实例.

yes, it is possible; You'll need to include the "identity" in the pickled result some how; the most natural being to use __getnewargs__ and have a __new__ method return the existing, cached instance in that case.

import uuid
import weakref


class Foo(object):
    ident_cache = weakref.WeakValueDictionary()

    def __new__(cls, identity=None, **kwargs):
        if identity is None:
            identity = uuid.uuid1()
        try:
            self = cls.ident_cache[identity]
        except KeyError:
            self = super(Foo, cls).__new__(cls)
            self.__identity = identity
            self.__init__(**kwargs)
            cls.ident_cache[identity] = self
        return self

    def __getnewargs__(self):
        return (self.__identity,)

    def __init__(self, foo):
        self.foo = foo

>>> import pickle
>>> a = Foo(foo=1)
>>> b = pickle.loads(pickle.dumps(a, pickle.HIGHEST_PROTOCOL))
>>> a is b
True

重要的一点是,您必须使用协议版本2(假设为更高版本);因为否则,将永远不会调用__new__.这只是pickle.dumps上的一个问题,loads不在乎.

The important note is that you must use protocol version 2 (or higher, hypothetically); because otherwise, __new__ is never called. This is only a concern on pickle.dumps, loads doesn't care.

这篇关于Python酸洗保持对象身份的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆