2

我有这样的课:

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 建议我只希望我的一部分字段被腌制?

4

2 回答 2

5

如文档中所述,Pickle 可以通过三种方式进行自定义。

  • 提供__getstate____setstate__方法。
  • 提供__getnewargs__/ __getnewargs_ex__(以及接受这些参数的构造函数)。
  • 提供__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__.items() if k not in self._blacklist}
def __setstate__(self, state):
    self.__dict__.update(state)

请参阅 gnibbler 对这个问题的评论:如果您正在做一些通用的事情,您应该认真考虑提出某种命名约定,而不是在每个类中放置一个黑名单。任何了解或了解约定的读者都会立即知道哪些属性是“缓存”值而不是“真实”值的一部分,事情的工作原理会更加明显,每个类中你要做的工作更少,并且用错字搞砸的地方越来越少……</p>

于 2013-11-15T01:28:59.507 回答
2

是的,您可以使用特殊方法__getstate____setstate__让 pickle 为您的对象保存自定义数据。

http://docs.python.org/2/library/pickle.html#object。获取状态

这应该让你开始:

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']
于 2013-11-15T01:27:41.033 回答