invoking a method from two superclasses

Scott David Daniels Scott.Daniels at Acm.Org
Tue Jun 30 19:49:18 EDT 2009


Mitchell L Model wrote:
> In Python 3, how should super() be used to invoke a method defined in C
 > that overrides its two superclasses A and B, in particular __init__?
> ...
> I've discovered the surprising fact described in the documentation of super
> <http://docs.python.org/3.1/library/functions.html#super>
> that specifying a class as the first argument of super means to skip that class when
> scanning the mro so that ....
> 
> This seems weird. Would someone please give a clear example and explanation of
> the recommended way of initializing both superclasses in a simple multiple inheritance
> situation?

OK, in Diamond inheritance in Python (and all multi-inheritance is
diamond-shaped in Python), the common ancestor must have a method
in order to properly use super.  The mro is guaranteed to have the
top of the split (C below) before its children in the mro, and the
join point (object or root below) after all of the classes from
which it inherits.

So, the correct way to do what you want:
     class A:
         def __init__(self):
             super().__init__()
             print('A')

     class B:
         def __init__(self):
             super().__init__()
             print('B')

     class C(A, B):
         def __init__(self):
             super().__init__()
             print('C')

     C()

And, if you are doing it with a message not available in object:

     class root:
         def prints(self):
             print('root') # or pass if you prefer

     class A(root):
         def prints(self):
             super().prints()
             print('A')

     class B(root):
         def prints(self):
             super().prints()
             print('B')

     class C(A, B):
         def prints(self):
             super().prints()
             print('C')

     C().prints()

--Scott David Daniels
Scott.Daniels at Acm.Org



More information about the Python-list mailing list