Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I would use the pickler's documented support for persistent object references. Persistent object references are objects that are referenced by the pickle but not stored in the pickle.</p> <p><a href="http://docs.python.org/library/pickle.html#pickling-and-unpickling-external-objects" rel="noreferrer">http://docs.python.org/library/pickle.html#pickling-and-unpickling-external-objects</a></p> <p>ZODB has used this API for years, so it's very stable. When unpickling, you can replace the object references with anything you like. In your case, you would want to replace the object references with markers indicating that the objects could not be pickled.</p> <p>You could start with something like this (untested):</p> <pre><code>import cPickle def persistent_id(obj): if isinstance(obj, wxObject): return "filtered:wxObject" else: return None class FilteredObject: def __init__(self, about): self.about = about def __repr__(self): return 'FilteredObject(%s)' % repr(self.about) def persistent_load(obj_id): if obj_id.startswith('filtered:'): return FilteredObject(obj_id[9:]) else: raise cPickle.UnpicklingError('Invalid persistent id') def dump_filtered(obj, file): p = cPickle.Pickler(file) p.persistent_id = persistent_id p.dump(obj) def load_filtered(file) u = cPickle.Unpickler(file) u.persistent_load = persistent_load return u.load() </code></pre> <p>Then just call dump_filtered() and load_filtered() instead of pickle.dump() and pickle.load(). wxPython objects will be pickled as persistent IDs, to be replaced with FilteredObjects at unpickling time.</p> <p>You could make the solution more generic by filtering out objects that are not of the built-in types and have no <code>__getstate__</code> method.</p> <p><strong>Update</strong> (15 Nov 2010): Here is a way to achieve the same thing with wrapper classes. Using wrapper classes instead of subclasses, it's possible to stay within the documented API.</p> <pre><code>from cPickle import Pickler, Unpickler, UnpicklingError class FilteredObject: def __init__(self, about): self.about = about def __repr__(self): return 'FilteredObject(%s)' % repr(self.about) class MyPickler(object): def __init__(self, file, protocol=0): pickler = Pickler(file, protocol) pickler.persistent_id = self.persistent_id self.dump = pickler.dump self.clear_memo = pickler.clear_memo def persistent_id(self, obj): if not hasattr(obj, '__getstate__') and not isinstance(obj, (basestring, int, long, float, tuple, list, set, dict)): return "filtered:%s" % type(obj) else: return None class MyUnpickler(object): def __init__(self, file): unpickler = Unpickler(file) unpickler.persistent_load = self.persistent_load self.load = unpickler.load self.noload = unpickler.noload def persistent_load(self, obj_id): if obj_id.startswith('filtered:'): return FilteredObject(obj_id[9:]) else: raise UnpicklingError('Invalid persistent id') if __name__ == '__main__': from cStringIO import StringIO class UnpickleableThing(object): pass f = StringIO() p = MyPickler(f) p.dump({'a': 1, 'b': UnpickleableThing()}) f.seek(0) u = MyUnpickler(f) obj = u.load() print obj assert obj['a'] == 1 assert isinstance(obj['b'], FilteredObject) assert obj['b'].about </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload