Is inheritance broken?

Alex Martelli aleaxit at yahoo.com
Thu Mar 29 04:29:37 EST 2001


"Jonathan Claggett" <jcc.ugm at ix.netcom.com> wrote in message
news:mailman.985808317.25055.python-list at python.org...
> >    Jonathan> Isn't this wrong?
> >
> >Nope.  It's a feature of multiple inheritance, not a bug.  The search
> >through base classes is left-to-right, depth first, thus
> >parallelogram.angle is found before rectangle.angle.
>
> Thank you, I think I understand now. I think the problem is that the depth
> first searching works fine so long as you don't have a common ancestor in
> your class tree. If you do have a common ancestor, it will be searched
ahead
> of some of its descendant classes.

Good summary.

> I wonder if there is a (quick) way to do
> a depth first search that accounts for common ancestors...

Not all that quick, but, what about...:


# a toy example of the potential problem-case:
class ancestor:
    def a(self): return 'ancestor.a'
    def b(self): return 'ancestor.b'
class descen_a(ancestor):
    def a(self): return 'descen_a.a'
class descen_b(ancestor):
    def b(self): return 'descen_b.b'
class desc_both(descen_a, descen_b):
    pass

# let's show the problem in action:
db = desc_both()
print db.a()
print db.b()

# a function to diagnose this possible problem:
def study(obj, attrib_name):
    attrib = getattr(obj.__class__, attrib_name)
    at_clas = attrib.im_class
    print 'Found:', attrib
    for base in obj.__class__.__bases__:
        found = getattr(base, attrib_name, None)
        if found is not None and found != attrib:
            print '  also:', found,
            fo_clas = found.im_class
            if issubclass(fo_clas, at_clas):
                print "(potential problem, override ignored)"
            else:
                print "(no problem, unrelated)"

# let's show the function at work:
print
study(db, 'a')
study(db, 'b')



D:\>python a.py
descen_a.a
ancestor.b

Found: <unbound method descen_a.a>
  also: <unbound method ancestor.a> (no problem, unrelated)
Found: <unbound method ancestor.b>
  also: <unbound method descen_b.b> (potential problem, override ignored)


Alex






More information about the Python-list mailing list