By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,364 Members | 1,623 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,364 IT Pros & Developers. It's quick & easy.

Pickling a class with a __getattr__

P: n/a
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 works but is not good enough.

$ python2.4
>>import cPickle as pickle
class Dict(dict):
.... pass
....
>>>

friend = Dict(name='Zahid', age=40)
friend
{'age': 40, 'name': 'Zahid'}
>>v=pickle.dumps(friend)
p=pickle.loads(v)
p
{'age': 40, 'name': 'Zahid'}

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'? I've got my reasons for not going for a simple type dict but
feel that that is irrelevant right now.

Apr 1 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
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
Apr 1 '07 #2

P: n/a
On Apr 1, 5:48 pm, Peter Otten <__pete...@web.dewrote:
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.

Apr 1 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.