我不知道__setstate__
和 __getstate__
方法的作用,所以举个简单的例子帮我。
Answers:
这是一个非常简单的Python示例,应该补充pickle docs。
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: " + repr(d))
self.__dict__ = d
self.val *= 3
import pickle
f = Foo()
f_data = pickle.dumps(f)
f_new = pickle.loads(f_data)
最小的例子
不管发生什么getstate
,都会进入setstate
。它不一定是命令。
无论发生什么事的出来getstate
一定是pickeable,如基本的内置插件等组成int
,str
,list
。
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__
就像https://stackoverflow.com/a/1939384/895245一样,是一个不错的选择,但是我们可以自己构造一个以更好地了解发生了什么:
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
,则默认为:
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__
默认获取并设置期望元组
如果要重用默认值__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 d.i == 1
assert d.j == 2
继承风俗 __getstate__
没有__slots__
它很容易,因为__dict__
forD
包含__dict__
for C
,所以我们根本不需要触摸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 d.i == 1
assert d.j == 2
继承与 __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 d.i == 1
assert d.j == 2
不幸的是,无法重用默认值__getstate__
和__setstate__
基本值:https : //groups.google.com/forum/#!topic/python-ideas/QkvOwa1-pHQ我们被迫定义它们。
在Python 2.7.12上测试。GitHub上游。