Why do calls of super() methods behave different for __init__ and standard methods?

Duncan Booth duncan at NOSPAMrcp.co.uk
Wed May 14 05:47:54 EDT 2003


Mirko Zeibig <mirko-lists at zeibig.net> wrote in 
news:b9t076$lgm$1 at news.web.de:

> So: __init__ is called for every Parentclass of D, whereas "display" 
> just uses the implementation of A and not of B.
> 
> Besides: if I comment or delete the super(...).__init__() calls in 
> classes A and B, only the __init__method of A is called!
> 
As you have seen, you need to explicitly call the methods using super if 
you want all the base class methods to be called. 

As you have it at present, D.__init__ calls C.__init__ which calls 
A.__init__ which calls B.__init__ which calls object.__init__.

D.display calls C.display which calls A.display, but A.display doesn't make 
a super call so the chain stops there.

The catch of course is that you can safely propogate __init__ all the way 
up to calling object.__init__, but if you just blindly put a call in 
A.display to super(A, self).display(), then it will work for instances of C 
and D, but if you try to create an A directly it will try to pass the call 
to object.display, which doesn't exist.

You could do something like this:

class A(object):
	def __init__(self):
		self.__super = super(A, self)
		self.__super.__init__()
		print "Ctr A"
		
	def display(self):
		print "A.display"
		if hasattr(self.__super, "display"):
			self.__super.display()

Or, you could define a new base class to safely terminate the call chain:

class IDisplayable(object):
    def display(self): pass

class A(IDisplayable):
    ...
    def display(self):
        print "A.display"
        super(A, self).display()

class B(IDisplayable):
    ... etc.
   
-- 
Duncan Booth                                             duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?




More information about the Python-list mailing list