我有一个这样的课程:
class Something(object):
def __init__(self):
self._thing_id
self._cached_thing
@property
def thing(self):
if self._cached_thing:
return self._cached_thing
return Thing.objects.get(id=self._thing_id)
当像这样腌制对象时,我想阻止_cached_thing
字段的腌制,因为它是易变的,并且是一种特别仅在内存中的实现。
有没有办法向Pickle建议我只想要我的一部分字段被腌制?
答案 0 :(得分:4)
Pickle可以通过三种方式进行自定义,如the docs中所述。
__getstate__
和__setstate__
方法。__getnewargs__
(以及采用这些参数的构造函数)。__reduce__
(以及让__reduce__
反转它的功能)。第一个通常是最简单的:
class Something(object):
def __init__(self):
self._thing_id
self._cached_thing
def __getstate__(self):
return self._thing_id
def __setstate__(self, thing_id):
self._thing_id = thing_id
# etc.
如果你想要更通用的东西,那将挑选所有的值(包括由子类设置的那些值,或者在创建后动态地等)除了你的黑名单,注意默认是“实例的__dict__
被腌制“,所以只需过滤:
_blacklist = ['_cached_thing']
def __getstate__(self):
return {k: v for k, v in self.__dict__.iteritems() if k not in self._blacklist}
def __setstate__(self, state):
self.__dict__.update(state)
请看gnibbler对这个问题的评论:如果你做的是通用的,你应该认真考虑提出某种命名约定,而不是在每个类中加入黑名单。任何了解或学习惯例的读者都会立即知道哪些属性是“缓存”值,而不是“真实”值的一部分,事情会更明显,每个班级的工作量都会减少,而且用拼写错误搞错的地方......
答案 1 :(得分:2)
是的,您可以使用特殊方法__getstate__
和__setstate__
让pickle为您的对象保存自定义数据。
http://docs.python.org/2/library/pickle.html#object.getstate
这应该让你开始:
class Something(object):
def __init__(self):
self._thing_id = 0
self._cached_thing = None
def __getstate__(self):
return {
'_thing_id': self._thing_id,
}
def __setstate(self, state):
self._thing_id = state['_thing_id']