Pickling a class with a __getattr__

Peter Bengtsson peterbe at gmail.com
Sun Apr 1 13:06:34 EDT 2007


On Apr 1, 5:48 pm, Peter Otten <__pete... at web.de> wrote:
> Peter Bengtsson wrote:
> > Hi, I'm trying to pickle an object instance of a class that is like a
> > dict but with a __getattr__ and I'm getting pickling errors.
> > This is what happens when I'm trying to be clever:
>
> >>>> import cPickle as pickle
> >>>> class Dict(dict):
> > ...     def __getattr__(self, key):
> > ...             return self.__getitem__(key)
> > ...
> >>>> friend = Dict(name='Zahid', age=40)
> >>>> friend
> > {'age': 40, 'name': 'Zahid'}
> >>>> friend.name
> > 'Zahid'
> >>>> v=pickle.dumps(friend)
> > Traceback (most recent call last):
> >   File "<stdin>", line 1, in ?
> >   File "/usr/lib/python2.4/copy_reg.py", line 73, in _reduce_ex
> >     getstate = self.__getstate__
> >   File "<stdin>", line 3, in __getattr__
> > KeyError: '__getstate__'
>
> > Why can't I pickle the slightly more featurefull class there called
> > 'Dict'?
>
> Because you allow your __getattr__() implementation to raise the wrong kind
> of exception.
>
> >>> from cPickle import dumps, loads
> >>> class Dict(dict):
>
> ...     def __getattr__(self, key):
> ...             try:
> ...                     return self[key]
> ...             except KeyError:
> ...                     raise AttributeError
> ...>>> friend = Dict(name="Zaphod", age=42)
> >>> v = dumps(friend)
> >>> p = loads(v)
> >>> p
>
> {'age': 42, 'name': 'Zaphod'}
>
> Peter

Thanks! That did the trick. I also noticed that I could define
__getstate__ and __setstate__ (needed for protocol 2) but your
solution works much better.




More information about the Python-list mailing list