super() and automatic method combination

Duncan Booth duncan.booth at invalid.invalid
Wed May 18 09:33:04 EDT 2005


Paul Rubin wrote:

> I'm trying the super() function as described in Python Cookbook, 1st
> ed, p. 172 (Recipe 5.4).
> 
>     class A(object):
>         def f(self):
>                 print 'A'
> 
> 
>     class B(object):
>         def f(self):
>                 print 'b'
> 
> 
>     class C(A,B):
>         def f(self):
Typo? 'c' should be 'C' in:
>                 super(c,self).f()
>                 print 'C'
> 
>     def test(cls):
>        x = cls()
>        x.f()
> 
>     test(C)
> 
> I have the impression that this is supposed to call the f method
> in both A and B, so it should print
>    A
>    B
>    C
> or maybe
>   B
>   A
>   C
> depending on the resolution order.  However, it only calls A.f and not
> B.f. 

You misunderstand. A single call to super only calls the next method in the 
chain. You have to include calls to super at all levels except for the 
ultimate base class.

> 
> I also notice that if I say
> 
> 
>     class B(object):
>         def f(self):
>             super(B,self).f()
>             print 'b'
> 
> then 
>   test(B)
> raises an exception since B has no superclass with an f method.  That
> doesn't seem like such a good thing necessarily.

You have to terminate the chain somehow. e.g.

class MyBase(object):
    	def f(self):
    	   print "MyBase"

class A(MyBase):
    def f(self):
        super(A, self).f()
        print "A"
    	...
class B(MyBase):
    def f(self):
        super(B, self).f()
        print "B"
    	...

> 
> Anyway, is there a preferred way of writing this example so that C.f
> automatically calls both A.f and B.f?

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.




More information about the Python-list mailing list