invoking a method from two superclasses
Scott David Daniels
Scott.Daniels at Acm.Org
Tue Jun 30 23:57:27 EDT 2009
Mitchell L Model wrote:
>> From: Scott David Daniels <Scott.Daniels at Acm.Org>
>> Date: Tue, 30 Jun 2009 16:49:18 -0700
>> Message-ID: <ieudnfm_J89EP9fXnZ2dnUVZ_g6dnZ2d at pdx.net>
>> Subject: Re: invoking a method from two superclasses
>>
>> 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
>>
>
> Great explanation, and 1/2 a "duh" to me. Thanks.
> What I was missing is that each path up to and including the top of the diamond
> must include a definition of the method, along with super() calls to move the method
> calling on its way up. Is this what the documentation means by
> "cooperative multiple inheritance"?
I expect so.
> ... Again, many thanks for the quick and clear response.
Since you know exactly what is confusing right now, and
what the resolution is, could I lean on you to take a stab
at improving the explanation? I think I know what the
solution is, but I don't have a good handle on what needs
explaining and what is easily understood. If you do something,
others can fix it where it doesn't work.
--Scott David Daniels
Scott.Daniels at Acm.Org
More information about the Python-list
mailing list