I don't understand why I'm getting the following behaviour when using super() with multiple inheritance. The following is a minimal example demonstrating the behaviour.
I have a diamond class hierarchy as follows: o | B / \ P N \ / M where: o = object B = BaseClass P = PClass N = NClass M = MyClass Inside MyClass().method(n), I dispatch to either NClass.method() or PClass.method() depending on the value of the argument n. The correct class is called, but then the *other* class method is called as well. E.g. this is what I expect: MyClass().method(2) -> calls PClass.method -> calls BaseClass.method but this is what I get: MyClass().method(2) -> calls PClass method -> calls NClass.method -> calls BaseClass.method and similarly for negative arguments, swapping PClass and NClass. First off, is this the expected behaviour? I seems strange to me, can somebody explain why it is the nominally correct behaviour? Secondly, how should I deal with this situation? Avoid super() altogether? Avoid multiple inheritance? Do something else? Demonstration code follows, using doctest to demonstrate the failure and the call pattern. ### fail.py import sys class BaseClass(object): def method(self, n): """Return something. n must not be 0, 1 or -1. >>> instance = BaseClass() >>> instance.method(7) 8 >>> instance.method(-5) -4 """ assert int(n) == n and n not in (-1, 0, 1) return n + 1 class PClass(BaseClass): """Deal with positive n.""" def method(self, n): """Return something. n must be strictly > 1. >>> instance = PClass() >>> instance.method(4) 6 """ print >>sys.stderr, "Called from PClass" assert int(n) == n and n > 1 return 1 + super(PClass, self).method(n) class NClass(BaseClass): """Deal with negative n.""" def method(self, n): """Return something. n must be strictly < -1. >>> instance = NClass() >>> instance.method(-4) -2 """ print >>sys.stderr, "Called from NClass" assert int(n) == n and n < -1 return 1 + super(NClass, self).method(n) class MyClass(PClass, NClass): def method(self, n): """Return something useful. >>> instance = MyClass() >>> instance.method(12) 14 >>> instance.method(-12) -10 """ #print >>sys.stderr, "Calling itoa with base=%d" % base if n > 0: print >>sys.stderr, "About to call PClass" parent = PClass else: print >>sys.stderr, "About to call NClass" parent = NClass return parent.method(self, n) if __name__ == '__main__': import doctest doctest.testmod() -- Steven -- http://mail.python.org/mailman/listinfo/python-list