invoking a method from two superclasses

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Wed Jul 1 00:15:06 EDT 2009


En Tue, 30 Jun 2009 21:34:02 -0300, Mitchell L Model  
<MLMLists at comcast.net> escribió:

> Allow me to add to my previous question that certainly the superclass
> methods can be called explicitly without resorting to super(), e.g.:
>
>     class C(A, B):
>         def __init__(self):
>             A.__init__(self)
>             B.__init__(self)
>
> My question is really whether there is any way of getting around the
> explicit class names by using super() and if not, shouldn't the  
> documentation
> of super point out that if more than one class on the mro defines a  
> method
> only the first will get called?

super returns [a proxy to] the *next* class in the MRO chain; it may or  
may not be a superclass of C (it may be a sibling class instead). If you  
know that only A B and C are involved and no other subclass ever exists,  
yes, you can explicitely invoke A.__init__ and B.__init__. If not (and  
this covers the vast majority of cases) using super in all places is the  
only way to get correct results (for details, see the "Harmful" article by  
James Knight [1] that someone has already referenced)

Note that doing it right with __init__ is tricky: usually, cooperative  
methods share the same signature so the super() call just passes the same  
arguments to the next class in the chain. But isn't uncommon for __init__  
to have different signatures for different subclasses; the article [1]  
contains a recipe for this case.

> What's strange is that it specifically mentions diamond patterns, which  
> is an important caseto get right, but it doesn't show how.

The "typical superclass call" in the 2.6 docs is, uhm, typical :) - in  
principle you use it everywhere you have cooperative classes. For the sake  
of completeness I'll copy it here:

class C(A, B):
     def method(self, arg):
         super(C, self).method(arg)

(you may simply use super().method(arg) in Python 3). Every implementation  
of method() in the class hierarchy should contain a super call like above  
(well, it gets somewhat more complex due to error handling, but you get  
the idea...)

In addition to the "Harmful" document, consider reading the three-article  
series by M. Simionato [2] which explains the problem from a different  
point of view.

[1] Python's Super Considered Harmful
http://fuhm.net/super-harmful/

[2] http://www.artima.com/weblogs/viewpost.jsp?thread=236275

-- 
Gabriel Genellina




More information about the Python-list mailing list