如何阻止Python中属性被序列化
我正在使用gnosis.xml.pickle这个工具,把我自己定义的一个类的对象转换成xml格式。这个对象是这样初始化的:
self.logger = MyLogger()
但是当我试图把这个对象保存成字符串时,出现了一个错误,提示说这个工具遇到了一个无法被转换的类型(thread.lock)。
有没有办法给logger这个属性加个标记,让这个工具知道不要尝试去转换这个属性呢?
3 个回答
3
你的类可以实现一个特殊的方法 __getstate__
,这个方法可以返回实例中你想要被保存的部分。
这个方法还有几种不同的变体(不过 __getstate__
和它的可选搭档方法 __setstate__
是最常用的)——你可以查看网上的 Python 文档页面,关于 pickle
的部分,我之前已经提到过,因为它正好是记录 __getstate__
的地方。
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)
40
你可以在你的类里定义两个方法,__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__
方法则应该用提供的字典来设置你的对象。
def __setstate__(self, d):
self.__dict__.update(d) # I *think* this is a safe way to do it
需要注意的是,在反序列化的时候,__init__
方法不会被调用,所以你需要在 __setstate__
方法里创建你的日志记录器。