Rewriting __getattr__

kost BebiX k.bx at ya.ru
Fri Jan 7 16:51:53 EST 2011


07.01.2011, 23:48, "Fuzzyman" <fuzzyman at gmail.com>:
> On Jan 7, 3:18 pm, kost BebiX <k... at ya.ru>; wrote:
>
>>  07.01.2011, 17:14, "Jean-Michel Pichavant" <jeanmic... at sequans.com>;:
>>>  kost BebiX wrote:
>>>>  šSorry for top posting, didn't know about that) I'm quote new to posting to mailing lists.
>>>>  šWell, actually the code you showed doesn't work)
>>>>>>>  šclass A(object):
>>>>  š.. ššššdef __init__(self):
>>>>  š.. ššššššššself.d = {}
>>>>  š.. ššššdef __getattr__(self, key):
>>>>  š.. šššššššštry:
>>>>  š.. ššššššššššššreturn self.d[key]
>>>>  š.. ššššššššexcept KeyError:
>>>>  š.. ššššššššššššraise AttributeError
>>>>>>>  šfrom copy import deepcopy
>>>>>>>  ša = A()
>>>>>>>  šdeepcopy(a)
>>>>  šException RuntimeError: 'maximum recursion depth exceeded while calling a Python object' in <type 'exceptions.AttributeError'> ignored
>>>>  šException RuntimeError: 'maximum recursion depth exceeded while calling a Python object' in <type 'exceptions.AttributeError'> ignored
>>>>  š0: <__main__.A object at 0xda0250>
>>>  It does work as I pasted it with python2.5.
>>>  recursion problems often occur when overriding __getattr__ or
>>>  __getattribute__ *AND* accessing self attributes using self.attr form
>>>  inside the method.
>>>  try to change
>>>  ššššreturn self.d[key]
>>>  into
>>>  ššššreturn object.__getattribute__(self, 'd')[key]
>>>  Just speculating though, I cannot test since I don't reproduce the problem.
>>>  JM
>>  Yeap, that works. So, is it a python 2.6 bug? Because documentation says that __getattr__ is called only after property was not found (and __getattr__ was actually invented in a way that you can use self inside it).
>
> That is true (that __getattr__ is called only if the attribute doesn't
> exist), however deepcopy works by creating a new instance *without*
> calling __init__. When it is copying the attributes self.d *doesn't*
> exist initially. You should work around this case in your __getattr__
> if you want your object to be deep-copyable.
>
> Michael Foord
> --
> http://www.voidspace.org.uk/

Yeah, but, I mean, shouldn't deepcopy copy the attributes before it gets to calling __getattr__?



More information about the Python-list mailing list