Is inheritance broken?

Skip Montanaro skip at pobox.com
Wed Mar 28 13:21:19 EST 2001


    >>>> class square(rhombus, rectangle):
    ... 	pass
    ...
    >>> test_square = square()
    >>> print test_square.angle()
    variable
    >>> 

    Jonathan> It looks like the inherited angle method from rectangle is
    Jonathan> being ignored.

Yup.

    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.  If you reverse the order of the base
classes in the definition of the square class, angle() will return the
correct value, but side() will return "variable".  This points out a general
gotcha with multiple inheritance.  You can pick the search order (depth
first or breadth first), but you wind up living with your choice.

Here's a version that's perhaps clear(er):

    class parallelogram:
	def angle(self): return "variable"
	def side(self): return "variable"

    class rhombus(parallelogram):
	def side(self): return "same"

    class rectangle(parallelogram):
	def angle(self): return "90 degrees"

    class square1(rhombus, rectangle):
	pass

    class square2(rectangle, rhombus):
	pass

    s1 = square1()
    print "squares have", s1.angle(), "angles"
    print "squares have", s1.side(), "sides"

    s2 = square2()
    print "squares have", s2.angle(), "angles"
    print "squares have", s2.side(), "sides"

Someone with more Python years under their belt will have to answer why
Guido chose depth first instead of breadth first search for methods when
multiple inheritance is involved.  I'm pretty sure it's a choice that can't
be changed now, however.  There's probably too much code that relies on the
current semantics.

-- 
Skip Montanaro (skip at pobox.com)
(847)971-7098




More information about the Python-list mailing list