super confused

Duncan Booth duncan at NOSPAMrcp.co.uk
Wed Sep 10 04:13:39 EDT 2003


Daniel Klein <danielk at aracnet.com> wrote in 
news:63qrlv8p4sqt7mossa6kimfloa0au416f5 at 4ax.com:

> In Smalltalk, a message send to 'super' simply means to send a message
> to self but start looking in the superclass first for the method. I
> realize Smalltalk is a single-inheritance language, but doesn't
> explain why, in Python, you need to specify the class name as a
> parameter.

The problem is that super needs two classes to operate. It has to know the 
type of the object (which is why you pass it 'self'), but it also has to 
know where to start in the inheritance hierarchy. If super was a keyword 
with some magic properties, then it might be able to pick up the correct 
class automatically, but its actually just a boring ordinary function, so 
you have to tell it.

> 
> As an aside, you will notice in the 'append' method, there are two
> ways to do the same thing, and either way could be used in the other
> methods as well. Which brings up my second question: Is one way more
> correct/efficient/better/pick your adjective? I'm very inclined to use
> the 'super' method cos that means I won't have to worry about changing
> things in the future.
> 
Actually these do slightly different things:

> class ValidatedList(list):
>     ...
>     def append(self, objekt):
>         _validate(objekt)
> #        list.append(self, objekt)
>         super(ValidatedList,self).append(objekt)

If you were to subclass ValidatedList, and the subclass also inherits from 
another subclass of list, then the call through super might not call 
list.append directly.

class List2(list):
   def append(self, objekt):
       return super(List2, self).append(objekt)

class Painful(ValidatedList, List2):
   pass

ouch = Painful()
ouch.append('oops')

Calling ouch.append invokes ValidatedList.append which passes the call up 
to List2.append, which then calls list.append. If ValidatedList.append 
called list.append directly then a call to ouch.append would never pass 
through List2.append.

So when to use super, and when to call the base class directly? If you 
don't expect diamond inheritance hierarchies, and you aren't writing a 
general purpose library for other people, then I would probably want to 
invoke the base class directly. It's faster (if you care), but also clearer 
to read. If those conditions don't hold, then use super.

Either way use plenty of unit tests so that if at some time your 
assumptions no longer apply you'll find out about it quickly.

-- 
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