使用__setstate__和__getstate__的简单示例

我不知道__setstate____getstate__方法是做什么的,所以请帮助我一个简单的例子。

下面是Python 2的一个非常简单的例子,它应该补充pickle文档 。

 class Foo(object): def __init__(self, val=2): self.val = val def __getstate__(self): print "I'm being pickled" self.val *= 2 return self.__dict__ def __setstate__(self, d): print "I'm being unpickled with these values:", d self.__dict__ = d self.val *= 3 import pickle f = Foo() f_string = pickle.dumps(f) f_new = pickle.loads(f_string) 

最小的例子

无论从getstate出来,进入setstate 。 这不需要是一个字典。

无论getstate是什么,都必须是可读的,比如由intstrlist等基本的内build函数组成。

 class C(object): def __init__(self, i): self.i = i def __getstate__(self): return self.i def __setstate__(self, i): self.i = i assert pickle.loads(pickle.dumps(C(1), -1)).i == 1 

默认__setstate__

默认的__setstate__需要一个dict

self.__dict__是一个很好的select,正如在https://stackoverflow.com/a/1939384/895245 ,但我们可以自己构build一个更好地看到发生了什么:

 class C(object): def __init__(self, i): self.i = i def __getstate__(self): return {'i': self.i} assert pickle.loads(pickle.dumps(C(1), -1)).i == 1 

默认__getstate__

类似于__setstate__

 class C(object): def __init__(self, i): self.i = i def __setstate__(self, d): self.i = d['i'] assert pickle.loads(pickle.dumps(C(1), -1)).i == 1 

__slots__对象没有__dict__

如果对象有__slots__ ,那么它没有__dict__

如果你要实现getsetstate ,默认的ish方法是:

 class C(object): __slots__ = 'i' def __init__(self, i): self.i = i def __getsate__(self): return { slot: getattr(self, slot) for slot in self.__slots__ } def __setsate__(self, d): for slot in d: setattr(self, slot, d[slot]) assert pickle.loads(pickle.dumps(C(1), -1)).i == 1 

__slots__默认get和set需要一个元组

如果你想重用默认的__getstate____setstate__ ,你将不得不传递下面的元组:

 class C(object): __slots__ = 'i' def __init__(self, i): self.i = i def __getsate__(self): return (None, { slot: getattr(self, slot) for slot in self.__slots__ }) assert pickle.loads(pickle.dumps(C(1), -1)).i == 1 

我不确定这是什么

遗产

首先看到默认的酸洗工作:

 class C(object): def __init__(self, i): self.i = i class D(C): def __init__(self, i, j): super(D, self).__init__(i) self.j = j d = pickle.loads(pickle.dumps(D(1, 2), -1)) assert di == 1 assert dj == 2 

inheritance自定义__getstate__

没有__slots__很容易,因为D__dict__包含C__dict__ ,所以我们根本不需要碰到C

 class C(object): def __init__(self, i): self.i = i class D(C): def __init__(self, i, j): super(D, self).__init__(i) self.j = j def __getstate__(self): return self.__dict__ def __setstate__(self, d): self.__dict__ = d d = pickle.loads(pickle.dumps(D(1, 2), -1)) assert di == 1 assert dj == 2 

inheritance和__slots__

使用__slots__ ,我们需要转发到基类,并且可以传递元组:

 class C(object): __slots__ = 'i' def __init__(self, i): self.i = i def __getstate__(self): return { slot: getattr(self, slot) for slot in C.__slots__ } def __setstate__(self, d): for slot in d: setattr(self, slot, d[slot]) class D(C): __slots__ = 'j' def __init__(self, i, j): super(D, self).__init__(i) self.j = j def __getstate__(self): return ( C.__getstate__(self), { slot: getattr(self, slot) for slot in self.__slots__ } ) def __setstate__(self, ds): C.__setstate__(self, ds[0]) d = ds[1] for slot in d: setattr(self, slot, d[slot]) d = pickle.loads(pickle.dumps(D(1, 2), -1)) assert di == 1 assert dj == 2 

不幸的是,我们不得不重新使用基础的默认__getstate____setstate__ : https : __getstate__ / __setstate__ __getstate__ / __setstate__我们不得不定义它。

testingPython 2.7.12。 GitHub上游: https : //github.com/cirosantilli/python-cheat/blob/master/pickle_cheat.py

这些方法用于控制pickle模块如何清理和取消对象。 这通常是自动处理的,所以除非你需要重写一个类是如何被腌渍或取消的,否则你不需要担心。