使用__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
是什么,都必须是可读的,比如由int
, str
, list
等基本的内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__
如果你要实现get
和setstate
,默认的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模块如何清理和取消对象。 这通常是自动处理的,所以除非你需要重写一个类是如何被腌渍或取消的,否则你不需要担心。