问题
I am using gnosis.xml.pickle to convert an object of my own class to xml. The object is initialized so that:
self.logger = MyLogger()
But when I do dump the object to a string I get an exception stating that the pickler encountered an unpickleable type (thread.lock).
Is there a way to 'tag' the logger attribute so that pickler will know not to try and pickle that attribute?
回答1:
You can define two methods, __getstate__ and __setstate__, to your class to override the default pickling behavior.
http://docs.python.org/library/pickle.html#object.__getstate__
__getstate__ should return a dict of attributes that you want to pickle.
def __getstate__(self):
d = dict(self.__dict__)
del d['logger']
return d
__setstate__ should setup your object with the provided dict.
def __setstate__(self, d):
self.__dict__.update(d) # I *think* this is a safe way to do it
Note that __init__ won't be called when unpickling so you'll have to create your logger in __setstate__
回答2:
This might be a better solution since it will allow an object created via copy.deepcopy to still have a 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)
回答3:
Your class can implement the special method __getstate__ to return exactly what parts of an instance it wants to be pickled.
There are several possible variants on that (though __getstate__ and its optional companion method __setstate__ are most general) -- see the online Python doc page for pickle, to which I already pointed above because it's the one documenting __getstate__.
来源:https://stackoverflow.com/questions/2999638/how-to-stop-attributes-from-being-pickled-in-python