7.1.4 不可腌制的对象
并不是所有对象都是可腌制的。套接字、文件句柄、数据库连接以及其他运行时状态依赖于操作系统或其他进程的对象,其可能无法用一种有意义的方式保存。如果对象包含不可腌制的属性,则可以定义__getstate__()和__setstate__()来返回所腌制实例的状态的一个子集。
1__getstate__()方法必须返回一个对象,其中包含所腌制对象的内部状态。表示状态的一种便利方式是使用字典,不过值可以是任意的腌制对象。保存状态,然后在从pickle加载对象时将所保存的状态传入__setstate__()。
import pickle
class State:
def __init__(self,name):
self.name = name
def __repr__(self):
return 'state({!r})'.format(self.__dict__)
class MyClass:
def __init__(self,name):
print('MyClass.__init__({})'.format(name))
self._set_name(name)
def _set_name(self,name):
self.name = name
self.computed = name[::-1]
def __repr__(self):
return 'MyClass({!r}) (computed={!r})'.format(
self.name,self.computed)
def __getstate__(self):
state = State(self.name)
print('__getstate__ -> {!r}'.format(state))
return state
def __setstate__(self,state):
print('__setstate__({!r})'.format(state))
self._set_name(state.name)
inst = MyClass('name here')
print('Before:',inst)
dumped = pickle.dumps(inst)
reloaded = pickle.loads(dumped)
print('After:',reloaded)
这个例子使用了一个单独的State对象来保存MyClass的内部状态。从pickle加载MyClass的一个实例时,会向__setstate__()传入一个State实例,用来初始化这个对象。
警告:如果返回值为False,则对象解除腌制时不会调用__setstate__()。
运行结果: