super() and automatic method combination

Duncan Booth duncan.booth at invalid.invalid
Wed May 18 10:38:51 EDT 2005


Laszlo Zsolt Nagy wrote:

> 
>>The trick is that C.f only calls A.f, but A.f needs to end up calling
>>B.f when it is used in a C.
>>  
>>
> I believe your response only applies to single inheritance. For
> classes with muliple bases classes, you need to call the base methods
> one by one. 

super wouldn't be much use if it only applied to single inheritance.

If you have a class hierarchy:

class Base(object):
class A(Base): 
class B(Base):
class AB(A, B):

and each class has a method 'f' then in an instance of AB:

   super(AB, self).f() --> calls A.f()
   super(A, self).f() --> calls B.f()
   super(B, self).f() --> calls Base.f()

but in an instance of A:

   super(A, self).f() --> calls Base.f()

  
> 
> BTW I prefer to call the base methods in this form:
> 
> class AB(A,B):
>     def f(self):
>        A.f(self)
>        B.f(self)

Which is fine so long as nobody else tries to add further subclasses later:

class C(B): ...
class Mine(AB,C): ...

Mine().f()

Using super throughout this works (it calls f in Mine, AB, A, C, B, and 
then Base), but your explicit call to the base classes means that if you 
don't call C.f() explicitly from Mine it never gets called, and if you do 
call it explicitly from Mine it gets called *after* B.f() has been called 
(and B.f() probably ends up being called twice).

> 
> This arises the question: is there a difference between these:
> 
> super(A,self).f()  # I do not use to use this....
> A.f(self)
> 
They are totally different. Super passes the call along to the next method 
in the defined method resolution order (MRO): the only thing you can be 
sure of here is that super(A,self).f() will never call the method f defined 
in class A (whereas A.f() calls the method f defined in class A or one of 
its base classes).



More information about the Python-list mailing list