multiple inheritance and __getattr__
David C. Ullrich
dullrich at sprynet.com
Tue Jul 29 11:40:39 EDT 2008
In article <488e2e70$0$29472$426a74cc at news.free.fr>,
Bruno Desthuilliers <bdesth.quelquechose at free.quelquepart.fr> wrote:
> Enrico a écrit :
> > Hi there,
> > I have the following situation (I tryed to minimize the code to concentrate
> > on the issue):
> >
> >>>> class A(object):
> > def __getattr__(self, name):
> > print 'A.__getattr__'
> > if name == 'a': return 1
> > raise AttributeError('%s not found in A' % name)
> >
> >>>> class B(object):
> > def __getattr__(self, name):
> > print 'B.__getattr__'
> > if name == 'b': return 1
> > raise AttributeError('%s not found in B' % name)
> >
> > Both classes have a __getattr__ method.
> > Now I want to have a class that inherits from both so I write:
> >
> >>>> class C(B,A):
> > pass
> >
> > The problem arise when I try something like this:
> >>>> c=C()
> >>>> c.a
> > A.__getattr__
> > 1
> >>>> c.b
> > A.__getattr__
> >
> > Traceback (most recent call last):
> > File "<pyshell#47>", line 1, in <module>
> > c.b
> > File "<pyshell#42>", line 5, in __getattr__
> > raise AttributeError('%s not found in A' % name)
> > AttributeError: b not found in A
>
> That's what I would have expected.
>
> > I was expecting, after a fail in A.__getattr__, a call to the __getattr__
> > method of B but it seems that after A.__getattr__ fails the exception stops
> > the flow.
>
> Indeed. You explicitely raise, so the lookup stops here.
??? Surely the reason the lookup stops there is that a __getattr__
was _found_. In the code below the lookup is not continuing,
there's a _second_ lookup started by the request for super.__getattr__.
> You'd need to
> explicitely call on superclass instead to have B.__getattr__ called, ie:
>
> class A(object):
> def __getattr__(self, name):
> if name == 'a':
> return 1
> return super(A, self).__getattr__(name)
>
> class B(object):
> def __getattr__(self, name):
> if name == 'b':
> return 2
> return super(B, self).__getattr__(name)
>
> class C(A, B):
> pass
>
--
David C. Ullrich
More information about the Python-list
mailing list