pickling subclasses of dict/list
Greg Chapman
glc at well.com
Sun Jul 4 11:28:08 EDT 2004
On Sat, 03 Jul 2004 14:37:28 -0400, Edward Loper
<edloper at gradient.cis.upenn.edu> wrote:
>I'm having trouble pickling subclasses of dict when they contain cycles.
>
>Note that pickling dict's that contain cycles works just fine, as does
>pickling classes that contain cycles in their instance variables. E.g.:
>
> >>> d = {}
> >>> d[1] = d
> >>> print d
> >>> pickle.dump(d, open('d.pickle', 'w'))
> >>> print pickle.load(open('d.pickle'))
> {1: {...}}
>
>I tried several things with __getstate__, __reduce__, etc., but couldn't
>get this to work. Is there some magic that I'm missing? What's the
>best way to get around this? (And should I file this as a bug in
>pickle? Or am I just not seeing the right way to do it?)
>
I think the answer to this problem is to use the extended __reduce__ API
documented here:
http://www.python.org/peps/pep-0307.html
Your subclass's __reduce__ can return a dictitems (or listitems) iterator, the
items of which will get pickled after the subclass instance is memoized, thus
avoiding the infinite recursion. The following works for your simple example:
>>> class D(dict):
... def __reduce__(self):
... return (D, (), None, None, self.iteritems())
...
>>> d = D()
>>> d[1] = d
>>> pickle.dumps(d)
'c__main__\nD\np0\n(tRp1\nI1\ng1\ns.'
>>> s = _
>>> dd = pickle.loads(s)
>>> dd.items()
[(1, {1: {...}})]
---
Greg Chapman
More information about the Python-list
mailing list