From: Jean-Michel Pichavant on

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

 |  Next  |  Last
Pages: 1 2
Prev: enhancing 'list'
Next: Unable to install numpy