multiple inheritance and __getattr__

Enrico 4564 at 755189.45
Mon Jul 28 16:48:09 CEST 2008


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

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. So, if I did understand well, B.__getattr__ will be never called
"automatically". I don't know if this has a reason, if it is a design choice
or what else, any explanation is welcome.

Since A and B are not written by me I can only work on C. The solution that
comes to my mind is to define a __getattr__ also in C and write something
like:

>>> class C(A,B):
 def __getattr__(self, name):
  try:
   return A.__getattr__(self, name)
  except AttributeError:
   return B.__getattr__(self, name)

>>> c=C()
>>> c.a
A.__getattr__
1
>>> c.b
A.__getattr__
B.__getattr__
1

A better solution is welcome.
Many thanks, Enrico





More information about the Python-list mailing list