invoking a method from two superclasses

M

Mitchell L Model

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__?

class A:
def __init__(self):
print('A')

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


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

C()

Output is:
A
C

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 if C.__init__ includes the line
super(A, self).__init__()
what gets called is B.__init__, so that if I want to call __init__ of both classes the
definition of C should have both of the following lines:
super().__init__()
super(A, self).__init__()
and that
super(B, self).__init__()
does nothing because B is the last class in the mro.

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?

Note: I am EXTREMELY knowledgeable about OO, Python, and many OOLs.
I don't mean to be arrogant, I just want to focus the discussion not open it to a broad
interchange about multiple inheritance, the ways it can be used or avoided, etc. I just
want to know how to use super. The documentation states the following:

"There are two typical use cases for super. In a class hierarchy with single inheritance,
super can be used to refer to parent classes without naming them explicitly, thus
making the code more maintainable."

"The second use case is to support cooperative multiple inheritance in a dynamic
execution environment. This use case is unique to Python and is not found in
statically compiled languages or languages that only support single inheritance.
This makes it possible to implement "diamond diagrams" where multiple base
classes implement the same method."

"For both use cases, a typical superclass call looks like this:

class C(B):
def method(self, arg):
super().method(arg) # This does the same thing as:
# super(C, self).method(arg)
"

Though it claims to be demonstrating both cases, it is only demonstrating single
inheritance and a particular kind of multiple inheritance where the method is found
in only one class in the mro. This avoids situations where you want to call the
method anywhere it is found in the mro, or at least in the direct superclasses.
Perhaps __init__ is a special case, but I don't see how to figure out how to __init__
two superclasses of a class from the documentation. I often file "bug reports" about
documentation ambiguities, vagueness, incompletenesses, etc., but I don't want to
do so for this case until I've heard something definitive about how it should be
handled.

Thanks in advance.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,981
Messages
2,570,188
Members
46,732
Latest member
ArronPalin

Latest Threads

Top