2024-04-19 16:26:42 发布
网友
是否有任何方法可以保留pickled对象的身份,即使用下面的打印True:
True
import pickle class Foo: pass x = Foo() print(x is pickle.loads(pickle.dumps(x))) #False
我在Linux上使用cPickle和cpython3.x,不需要便携的东西。在
是的,这是可能的;您需要在pickled结果中包括“identity”;最自然的方法是使用__getnewargs__并使用__new__方法返回现有的缓存实例。在
__getnewargs__
__new__
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
重要的一点是,您必须使用协议版本2(或者更高版本,假设);否则,__new__永远不会被调用。这只是对pickle.dumps的关注,loads并不关心。在
pickle.dumps
loads
import pickle class Foo: _id_counter = 0 def __init__(self): self._id = Foo._id_counter Foo._id_counter += 1 x = Foo() print(x._id==pickle.loads(pickle.dumps(x))._id) # True
是的,这是可能的;您需要在pickled结果中包括“identity”;最自然的方法是使用
^{pr2}$__getnewargs__
并使用__new__
方法返回现有的缓存实例。在重要的一点是,您必须使用协议版本2(或者更高版本,假设);否则,
__new__
永远不会被调用。这只是对pickle.dumps
的关注,loads
并不关心。在相关问题 更多 >
编程相关推荐