Prev: enhancing 'list'
Next: Unable to install numpy
From: Jean-Michel Pichavant on 18 Jan 2010 12:54 >>> class SubClass(Base): >>> colour = "Red" >>> def parrot(self): >>> """docstring for Subclass""" >>> return super(Subclass, self).parrot() I'm not a big fan of super, but I'm still wondering if >>> return super(self.__class__, self).parrot() would have made it. What if Subclass has more than one base class ? JM
From: Duncan Booth on 18 Jan 2010 13:11 Jean-Michel Pichavant <jeanmichel(a)sequans.com> wrote: > >>>> class SubClass(Base): >>>> colour = "Red" >>>> def parrot(self): >>>> """docstring for Subclass""" >>>> return super(Subclass, self).parrot() > I'm not a big fan of super, but I'm still wondering if > > >>> return super(self.__class__, self).parrot() > > would have made it. No, it wouldn't. > What if Subclass has more than one base class ? super() will work in that case provided you specify the current class. It never works correctly if you specify the class of self. Consider another level of subclasses and it may be clearer: >>> class Base(object): def parrot(self): print "Base.parrot" >>> class SubClass(Base): def parrot(self): print "SubClass.parrot" return super(SubClass, self).parrot() >>> class SubSubClass(SubClass): def parrot(self): print "SubSubClass.parrot" return super(SubSubClass, self).parrot() >>> SubSubClass().parrot() SubSubClass.parrot SubClass.parrot Base.parrot >>> class SubClass(Base): def parrot(self): print "SubClass.parrot" return super(self.__class__, self).parrot() >>> class SubSubClass(SubClass): def parrot(self): print "SubSubClass.parrot" return super(self.__class__, self).parrot() >>> SubSubClass().parrot() SubClass.parrot SubClass.parrot SubClass.parrot SubClass.parrot SubClass.parrot SubClass.parrot SubClass.parrot SubClass.parrot SubClass.parrot .... (you're in an infinite loop now) ...
From: Jean-Michel Pichavant on 18 Jan 2010 14:50 Duncan Booth wrote: > Jean-Michel Pichavant <jeanmichel(a)sequans.com> wrote: > > >>>>> class SubClass(Base): >>>>> colour = "Red" >>>>> def parrot(self): >>>>> """docstring for Subclass""" >>>>> return super(Subclass, self).parrot() >>>>> >> I'm not a big fan of super, but I'm still wondering if >> >> >>>>> return super(self.__class__, self).parrot() >>>>> >> would have made it. >> > > No, it wouldn't. > > >> What if Subclass has more than one base class ? >> > > super() will work in that case provided you specify the current class. It > never works correctly if you specify the class of self. > > Consider another level of subclasses and it may be clearer: > > >>>> class Base(object): >>>> > def parrot(self): > print "Base.parrot" > > > >>>> class SubClass(Base): >>>> > def parrot(self): > print "SubClass.parrot" > return super(SubClass, self).parrot() > > > >>>> class SubSubClass(SubClass): >>>> > def parrot(self): > print "SubSubClass.parrot" > return super(SubSubClass, self).parrot() > > > >>>> SubSubClass().parrot() >>>> > SubSubClass.parrot > SubClass.parrot > Base.parrot > > >>>> class SubClass(Base): >>>> > def parrot(self): > print "SubClass.parrot" > return super(self.__class__, self).parrot() > > > >>>> class SubSubClass(SubClass): >>>> > def parrot(self): > print "SubSubClass.parrot" > return super(self.__class__, self).parrot() > > >>>> SubSubClass().parrot() >>>> > SubClass.parrot > SubClass.parrot > SubClass.parrot > SubClass.parrot > SubClass.parrot > SubClass.parrot > SubClass.parrot > SubClass.parrot > SubClass.parrot > ... (you're in an infinite loop now) ... > I see. Then is there a reason why >>> return super(Subclass, self).parrot() would be prefered over the "classic" >>> return Base.parrot(self) ? Or is it just a matter of preference ? JM
From: Arnaud Delobelle on 18 Jan 2010 15:19 Jean-Michel Pichavant <jeanmichel(a)sequans.com> writes: [...] > Then is there a reason why >>>> return super(Subclass, self).parrot() > would be prefered over the "classic" >>>> return Base.parrot(self) > ? > > Or is it just a matter of preference ? Using super() calls the next method in the class's Method Resolution Order (mro - to see it on class A, use A.mro()). This guarantees that ancestor methods won't be called twice when the inheritance graph is not a tree. Here is a (minimal?) example. >>> class A(object): .... def foo(self): print 'A' .... >>> class B(A): .... def foo(self): .... super(B, self).foo() .... print 'B' .... >>> class C(A): .... def foo(self): .... super(C, self).foo() .... print 'C' .... >>> class D(B, C): .... def foo(self): .... super(D, self).foo() .... print 'D' .... >>> d = D() >>> d.foo() A C B D >>> D.mro() [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>] The reason why super() may be necessary is that if an object is an instance of say class C, its method resolution order above class C is not known at compile time. HTH -- Arnaud
From: Gabriel Genellina on 18 Jan 2010 19:57
En Mon, 18 Jan 2010 16:50:45 -0300, Jean-Michel Pichavant <jeanmichel(a)sequans.com> escribi�: > Duncan Booth wrote: >> Jean-Michel Pichavant <jeanmichel(a)sequans.com> wrote: >> >> >>>>>> class SubClass(Base): >>>>>> colour = "Red" >>>>>> def parrot(self): >>>>>> """docstring for Subclass""" >>>>>> return super(Subclass, self).parrot() >>>>>> >>> I'm not a big fan of super, but I'm still wondering if >>> return super(self.__class__, self).parrot() >>> would have made it. >> >> No, it wouldn't. [...] >> > I see. > Then is there a reason why > return super(Subclass, self).parrot() > would be prefered over the "classic" > return Base.parrot(self) > ? > Or is it just a matter of preference ? For a longer explanation, see: James Knight: Python's Super Considered Harmful http://fuhm.net/super-harmful/ Michele Simionato: Things to Know About Python Super http://www.artima.com/weblogs/viewpost.jsp?thread=236275 http://www.artima.com/weblogs/viewpost.jsp?thread=236278 http://www.artima.com/weblogs/viewpost.jsp?thread=237121 -- Gabriel Genellina |