23

我正在使用 gnosis.xml.pickle 将我自己的类的对象转换为 xml。该对象被初始化,以便:

self.logger = MyLogger()

但是,当我将对象转储到字符串时,我得到一个异常,指出pickler 遇到了不可腌制的类型(thread.lock)。

有没有办法“标记”记录器属性,以便pickler 知道不要尝试腌制该属性?

4

3 回答 3

39

您可以为您的类定义两个方法__getstate____setstate__,以覆盖默认的酸洗行为。

http://docs.python.org/library/pickle.html#object.__getstate__

__getstate__应该返回要腌制的属性的字典。

def __getstate__(self):
    d = dict(self.__dict__)
    del d['logger']
    return d

__setstate__应该使用提供的 dict 设置您的对象。

def __setstate__(self, d):
    self.__dict__.update(d) # I *think* this is a safe way to do it

请注意,__init__取消腌制时不会被调用,因此您必须在其中创建记录器__setstate__

于 2010-06-08T17:46:56.200 回答
11

这可能是一个更好的解决方案,因为它允许通过创建的对象copy.deepcopy仍然具有self.logger

def __getstate__(self):
    d = self.__dict__.copy()
    if 'logger' in d:
        d['logger'] = d['logger'].name
    return d

def __setstate__(self, d):
    if 'logger' in d:
        d['logger'] = logging.getLogger(d['logger'])
    self.__dict__.update(d)
于 2014-09-26T15:44:29.063 回答
3

您的类可以实现特殊方法__getstate__以准确返回它想要腌制的实例的哪些部分。

有几种可能的变体(尽管__getstate__它的可选配套方法__setstate__是最通用的)——请参阅 的在线 Python 文档页面pickle,我已经在上面指出了这一点,因为它是记录__getstate__.

于 2010-06-08T17:45:27.873 回答