正如 Python 文档所述,虽然 using__reduce__
是一种有效的方法:
虽然功能强大,但__reduce__()
直接在类中实现很容易出错。因此,类设计者应尽可能使用高级接口(__getnewargs_ex__()
即__getstate__()
和__setstate__()
)
因此,我将解释如何使用更简单的高级接口__getstate__
并使__setstate__
对象可拾取。
让我们看一个非常简单的类,它有一个不可提取的属性,假设它是一个文件句柄。
class Foo:
def __init__(self, filename):
self.filename = filename
self.f = open(filename)
的实例Foo
不可选择:
obj = Foo('test.txt')
pickle.dumps(obj)
# TypeError: cannot pickle '_io.TextIOWrapper' object
__getstate__
我们可以通过分别实现和使用 pickle 使这个类可序列化和反序列化__setstate__
。
class Foo:
... # the class as it was
def __getstate__(self):
"""Used for serializing instances"""
# start with a copy so we don't accidentally modify the object state
# or cause other conflicts
state = self.__dict__.copy()
# remove unpicklable entries
del state['f']
return state
def __setstate__(self, state):
"""Used for deserializing"""
# restore the state which was picklable
self.__dict__.update(state)
# restore unpicklable entries
f = open(self.filename)
self.f = f
现在可以腌制了:
obj = Foo('text.txt')
pickle.dumps(obj)
# b'\x80\x04\x951\x00\x00\x00\x00\x00\x00\x00\x8c\x08[...]'
因此,在您的示例中,您可能会执行以下操作:
class MyComplicatedObject:
def __getstate__(self):
state = self.__dict__.copy()
del state['progress'] # remove the unpicklable progress attribute
return state
def __setstate__(self, state):
self.__dict__.update(state)
# restore the progress from the progress integer
self.progress = make_progress(self.progress_int)
在 Python 3.8+ 中,您还可以为 objects 实现自定义归约。