473,381 Members | 1,411 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,381 software developers and data experts.

Python 2.3.3 super() behaviour

Hi,

I hope this is not a FAQ, but I have trouble understanding the behaviour of
the super() built-in function. I've read the excellent book 'Python in a
Nutshell' which explains this built-in function on pages 89-90. Based on the
example on page 90, I wrote this test code :

class A(object):
def test(self):
print 'A'

class B(object):
def test(self):
print 'B'

class C(A,B):
def test(self):
super(C,self).test()
print 'C'

print C.__mro__
c=C()
c.test()

The output is :
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type
'object'>)
A
C

Whereas I was expecting :
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type
'object'>)
A
B
C

Was I wrong to expect this (based on what I've read ?)

Regards,
Nicolas


Jul 18 '05 #1
11 5007
Nicolas Lehuen wrote:
Hi,

I hope this is not a FAQ, but I have trouble understanding the behaviour
of the super() built-in function. I've read the excellent book 'Python in
a Nutshell' which explains this built-in function on pages 89-90. Based on
the example on page 90, I wrote this test code :

class A(object):
def test(self):
print 'A'

class B(object):
def test(self):
print 'B'

class C(A,B):
def test(self):
super(C,self).test()
print 'C'

print C.__mro__
c=C()
c.test()

The output is :
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type
'object'>)
A
C

Whereas I was expecting :
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type
'object'>)
A
B
C

Was I wrong to expect this (based on what I've read ?)


As soon as a test() method without the super(...).test() is reached, no
further test methods will be invoked. Only the first in the list of base
classes will be invoked. If I'm getting it right you have to do something
like:

class Base(object):
def test(self):
print "base"

class D1(Base):
def test(self):
super(D1, self).test()
print "derived 1"

class D2(Base):
def test(self):
super(D2, self).test()
print "derived 2"

class All(D1, D2):
pass

All().test()

Here all cooperating methods have a super() call, and the base class acts as
a showstopper to prevent that Python tries to invoke the non-existent
object.test().

Peter

Jul 18 '05 #2
OK, I get it now, thanks.

super() method calls should only be used for method involved in
diamond-shaped inheritance. This is logical since in this case the base
classe (from which the diamond-shaped inheritance starts) defines the
interface of the method.

This solves another question I was asking myself about super() : "how can it
work when the method signature differ between B and C ?". Answer : the
method signature should not change because polymorphic calls would be
greatly endangered. The base class defines the signature of the method which
must be followed by all its children, this way super() can work properly.

The base method signature is not enforced by Python, of course, but you'd
better respect it unless you get weird result in polymorphic calls.

Regards,
Nicolas

"Peter Otten" <__*******@web.de> a écrit dans le message de
news:c6*************@news.t-online.com...
Nicolas Lehuen wrote:
Hi,

I hope this is not a FAQ, but I have trouble understanding the behaviour
of the super() built-in function. I've read the excellent book 'Python in a Nutshell' which explains this built-in function on pages 89-90. Based on the example on page 90, I wrote this test code :

class A(object):
def test(self):
print 'A'

class B(object):
def test(self):
print 'B'

class C(A,B):
def test(self):
super(C,self).test()
print 'C'

print C.__mro__
c=C()
c.test()

The output is :
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type
'object'>)
A
C

Whereas I was expecting :
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type
'object'>)
A
B
C

Was I wrong to expect this (based on what I've read ?)
As soon as a test() method without the super(...).test() is reached, no
further test methods will be invoked. Only the first in the list of base
classes will be invoked. If I'm getting it right you have to do something
like:

class Base(object):
def test(self):
print "base"

class D1(Base):
def test(self):
super(D1, self).test()
print "derived 1"

class D2(Base):
def test(self):
super(D2, self).test()
print "derived 2"

class All(D1, D2):
pass

All().test()

Here all cooperating methods have a super() call, and the base class acts

as a showstopper to prevent that Python tries to invoke the non-existent
object.test().

Peter

Jul 18 '05 #3
The only problem I have is that I want to build a multiple inheritance
involving an object which does not cooperate, namely :

class T(object):
def __init__(self):
super(T,self).__init__()

class TL(list,object):
def __init__(self)
super(TL,self).__init__()

In this case, T.__init__ is not called, because list.__init__ does not use
super(). The only clean way to proceed is to change the inheritance order :
TL(T,list). This way, both constructors are called.

Here is another example which exhibits the behaviour :

class A(object):
def __init__(self):
super(A,self).__init__()
print 'A'

class B(object):
def __init__(self):
print 'B'

class C(B,A):
def __init__(self):
super(C,self).__init__()
print 'C'

class D(A,B):
def __init__(self):
super(D,self).__init__()
print 'D'
C() B
C
<__main__.C object at 0x008F3D70> D() B
A
D
<__main__.D object at 0x008F39F0>

The problem is that if you go further down the inheritance, the behaviour is
even more complicated :

class E(object):
def __init__(self):
super(E,self).__init__()
print 'E'

class F(C,E):
def __init__(self):
super(F,self).__init__()
print 'F'

class G(D,E):
def __init__(self):
super(G,self).__init__()
print 'G'
F() B
C
F
<__main__.F object at 0x008F3D70> G() B
A
D
G
<__main__.G object at 0x008F3EF0>

class H(E,C):
def __init__(self):
super(H,self).__init__()
print 'H'

class I(E,D):
def __init__(self):
super(I,self).__init__()
print 'I'
H() B
C
E
H
<__main__.H object at 0x008F3E30> I() B
A
D
E
I
<__main__.I object at 0x008F3FD0>

So the conclusion is : never do that :). Another more constructive
conclusion would be : always put the most cooperative classes first in the
inheritance declaration, provided that it doesn't interfere with your needs.
A class which has an uncooperative ancestor is less cooperative than a class
which has only cooperative ancestors.

Regards,
Nicolas

"Nicolas Lehuen" <ni************@thecrmcompany.com> a écrit dans le message
de news:40***********************@news.easynet.fr...
OK, I get it now, thanks.

super() method calls should only be used for method involved in
diamond-shaped inheritance. This is logical since in this case the base
classe (from which the diamond-shaped inheritance starts) defines the
interface of the method.

This solves another question I was asking myself about super() : "how can it work when the method signature differ between B and C ?". Answer : the
method signature should not change because polymorphic calls would be
greatly endangered. The base class defines the signature of the method which must be followed by all its children, this way super() can work properly.

The base method signature is not enforced by Python, of course, but you'd
better respect it unless you get weird result in polymorphic calls.

Regards,
Nicolas

"Peter Otten" <__*******@web.de> a écrit dans le message de
news:c6*************@news.t-online.com...
Nicolas Lehuen wrote:
Hi,

I hope this is not a FAQ, but I have trouble understanding the
behaviour of the super() built-in function. I've read the excellent book 'Python in a Nutshell' which explains this built-in function on pages 89-90. Based
on
the example on page 90, I wrote this test code :

class A(object):
def test(self):
print 'A'

class B(object):
def test(self):
print 'B'

class C(A,B):
def test(self):
super(C,self).test()
print 'C'

print C.__mro__
c=C()
c.test()

The output is :
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>,
<type 'object'>)
A
C

Whereas I was expecting :
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>)
A
B
C

Was I wrong to expect this (based on what I've read ?)


As soon as a test() method without the super(...).test() is reached, no
further test methods will be invoked. Only the first in the list of base
classes will be invoked. If I'm getting it right you have to do

something like:

class Base(object):
def test(self):
print "base"

class D1(Base):
def test(self):
super(D1, self).test()
print "derived 1"

class D2(Base):
def test(self):
super(D2, self).test()
print "derived 2"

class All(D1, D2):
pass

All().test()

Here all cooperating methods have a super() call, and the base class

acts as
a showstopper to prevent that Python tries to invoke the non-existent
object.test().

Peter


Jul 18 '05 #4
super is not going to be helpful here, so why not call the X.__init__
functions explicitly?
Since you *need* multiple __init__ calls from the multiply-inherited
class, super isn't going to work...

Nicolas Lehuen wrote:
The only problem I have is that I want to build a multiple inheritance
involving an object which does not cooperate, namely :

class T(object):
def __init__(self):
super(T,self).__init__()

class TL(list,object):
def __init__(self)
super(TL,self).__init__()

In this case, T.__init__ is not called, because list.__init__ does not use
super(). The only clean way to proceed is to change the inheritance order :
TL(T,list). This way, both constructors are called.

Here is another example which exhibits the behaviour :

class A(object):
def __init__(self):
super(A,self).__init__()
print 'A'

class B(object):
def __init__(self):
print 'B'

class C(B,A):
def __init__(self):
super(C,self).__init__()
print 'C'

class D(A,B):
def __init__(self):
super(D,self).__init__()
print 'D'

C()
B
C
<__main__.C object at 0x008F3D70>
D()
B
A
D
<__main__.D object at 0x008F39F0>

The problem is that if you go further down the inheritance, the behaviour is
even more complicated :

class E(object):
def __init__(self):
super(E,self).__init__()
print 'E'

class F(C,E):
def __init__(self):
super(F,self).__init__()
print 'F'

class G(D,E):
def __init__(self):
super(G,self).__init__()
print 'G'

F()
B
C
F
<__main__.F object at 0x008F3D70>
G()
B
A
D
G
<__main__.G object at 0x008F3EF0>

class H(E,C):
def __init__(self):
super(H,self).__init__()
print 'H'

class I(E,D):
def __init__(self):
super(I,self).__init__()
print 'I'

H()
B
C
E
H
<__main__.H object at 0x008F3E30>
I()
B
A
D
E
I
<__main__.I object at 0x008F3FD0>

So the conclusion is : never do that :). Another more constructive
conclusion would be : always put the most cooperative classes first in the
inheritance declaration, provided that it doesn't interfere with your needs.
A class which has an uncooperative ancestor is less cooperative than a class
which has only cooperative ancestors.

Regards,
Nicolas

"Nicolas Lehuen" <ni************@thecrmcompany.com> a écrit dans le message
de news:40***********************@news.easynet.fr...
OK, I get it now, thanks.

super() method calls should only be used for method involved in
diamond-shaped inheritance. This is logical since in this case the base
classe (from which the diamond-shaped inheritance starts) defines the
interface of the method.

This solves another question I was asking myself about super() : "how can


it
work when the method signature differ between B and C ?". Answer : the
method signature should not change because polymorphic calls would be
greatly endangered. The base class defines the signature of the method


which
must be followed by all its children, this way super() can work properly.

The base method signature is not enforced by Python, of course, but you'd
better respect it unless you get weird result in polymorphic calls.

Regards,
Nicolas

"Peter Otten" <__*******@web.de> a écrit dans le message de
news:c6*************@news.t-online.com...
Nicolas Lehuen wrote:
Hi,

I hope this is not a FAQ, but I have trouble understanding the


behaviour
of the super() built-in function. I've read the excellent book 'Python


in
a Nutshell' which explains this built-in function on pages 89-90.
Based
on
the example on page 90, I wrote this test code :

class A(object):
def test(self):
print 'A'

class B(object):
def test(self):
print 'B'

class C(A,B):
def test(self):
super(C,self).test()
print 'C'

print C.__mro__
c=C()
c.test()

The output is :
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>,


<type
'object'>)
A
C

Whereas I was expecting :
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>,
<type
'object'>)
A
B
C

Was I wrong to expect this (based on what I've read ?)

As soon as a test() method without the super(...).test() is reached, no
further test methods will be invoked. Only the first in the list of base
classes will be invoked. If I'm getting it right you have to do
something
like:

class Base(object):
def test(self):
print "base"

class D1(Base):
def test(self):
super(D1, self).test()
print "derived 1"

class D2(Base):
def test(self):
super(D2, self).test()
print "derived 2"

class All(D1, D2):
pass

All().test()

Here all cooperating methods have a super() call, and the base class


acts
as
a showstopper to prevent that Python tries to invoke the non-existent
object.test().

Peter



Jul 18 '05 #5
Ah, so there *is* more than one way to do it, then ? ;)

What the example shows is that super(...).__init__ does make one call to
each superclass' __init__, provided that those superclasses play nicely and
use super() themselves (as Peter wrote). If one of the superclasses does not
use super(), the 'magical' iteration over parent methods is interrupted,
hence the need to put those bad guys at the end of the superclasses list in
the class declaration.

But you're right, David, the simplest way to get what I want is to
explicitely call the superclasses' __init__. However, this would mean that
super() is not as useful as it seems. I'd rather find a way to *always* use
super() than have special cases for certain inheritance trees. In other
words, I'd rather have only one way to do it :).

Regards,
Nicolas

"David Fraser" <da****@sjsoft.com> a écrit dans le message de
news:c6**********@ctb-nnrp2.saix.net...
super is not going to be helpful here, so why not call the X.__init__
functions explicitly?
Since you *need* multiple __init__ calls from the multiply-inherited
class, super isn't going to work...

Nicolas Lehuen wrote:
The only problem I have is that I want to build a multiple inheritance
involving an object which does not cooperate, namely :

class T(object):
def __init__(self):
super(T,self).__init__()

class TL(list,object):
def __init__(self)
super(TL,self).__init__()

In this case, T.__init__ is not called, because list.__init__ does not use super(). The only clean way to proceed is to change the inheritance order : TL(T,list). This way, both constructors are called.

Here is another example which exhibits the behaviour :

class A(object):
def __init__(self):
super(A,self).__init__()
print 'A'

class B(object):
def __init__(self):
print 'B'

class C(B,A):
def __init__(self):
super(C,self).__init__()
print 'C'

class D(A,B):
def __init__(self):
super(D,self).__init__()
print 'D'

>C()


B
C
<__main__.C object at 0x008F3D70>
>D()


B
A
D
<__main__.D object at 0x008F39F0>

The problem is that if you go further down the inheritance, the behaviour is even more complicated :

class E(object):
def __init__(self):
super(E,self).__init__()
print 'E'

class F(C,E):
def __init__(self):
super(F,self).__init__()
print 'F'

class G(D,E):
def __init__(self):
super(G,self).__init__()
print 'G'

>F()


B
C
F
<__main__.F object at 0x008F3D70>
>G()


B
A
D
G
<__main__.G object at 0x008F3EF0>

class H(E,C):
def __init__(self):
super(H,self).__init__()
print 'H'

class I(E,D):
def __init__(self):
super(I,self).__init__()
print 'I'

>H()


B
C
E
H
<__main__.H object at 0x008F3E30>
>I()


B
A
D
E
I
<__main__.I object at 0x008F3FD0>

So the conclusion is : never do that :). Another more constructive
conclusion would be : always put the most cooperative classes first in the inheritance declaration, provided that it doesn't interfere with your needs. A class which has an uncooperative ancestor is less cooperative than a class which has only cooperative ancestors.

Regards,
Nicolas

"Nicolas Lehuen" <ni************@thecrmcompany.com> a écrit dans le message de news:40***********************@news.easynet.fr...
OK, I get it now, thanks.

super() method calls should only be used for method involved in
diamond-shaped inheritance. This is logical since in this case the base
classe (from which the diamond-shaped inheritance starts) defines the
interface of the method.

This solves another question I was asking myself about super() : "how can

it
work when the method signature differ between B and C ?". Answer : the
method signature should not change because polymorphic calls would be
greatly endangered. The base class defines the signature of the method


which
must be followed by all its children, this way super() can work

properly.
The base method signature is not enforced by Python, of course, but you'dbetter respect it unless you get weird result in polymorphic calls.

Regards,
Nicolas

"Peter Otten" <__*******@web.de> a écrit dans le message de
news:c6*************@news.t-online.com...

Nicolas Lehuen wrote:
>Hi,
>
>I hope this is not a FAQ, but I have trouble understanding the


behaviour
>of the super() built-in function. I've read the excellent book 'Python

in

>a Nutshell' which explains this built-in function on pages 89-90.


Based
on

>the example on page 90, I wrote this test code :
>
>class A(object):
> def test(self):
> print 'A'
>
>class B(object):
> def test(self):
> print 'B'
>
>class C(A,B):
> def test(self):
> super(C,self).test()
> print 'C'
>
>print C.__mro__
>c=C()
>c.test()
>
>The output is :
>(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>,


<type
>'object'>)
>A
>C
>
>Whereas I was expecting :
>(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>,


<type
>'object'>)
>A
>B
>C
>
>Was I wrong to expect this (based on what I've read ?)

As soon as a test() method without the super(...).test() is reached, no
further test methods will be invoked. Only the first in the list of baseclasses will be invoked. If I'm getting it right you have to do


something
like:

class Base(object):
def test(self):
print "base"

class D1(Base):
def test(self):
super(D1, self).test()
print "derived 1"

class D2(Base):
def test(self):
super(D2, self).test()
print "derived 2"

class All(D1, D2):
pass

All().test()

Here all cooperating methods have a super() call, and the base class


acts
as

a showstopper to prevent that Python tries to invoke the non-existent
object.test().

Peter



Jul 18 '05 #6
"Nicolas Lehuen" <ni************@thecrmcompany.com> wrote in message news:<40***********************@news.easynet.fr>.. .
Hi,

I hope this is not a FAQ, but I have trouble understanding the behaviour of
the super() built-in function.


Maybe this thread on super will interest you:

http://groups.google.it/groups?hl=it....lang.python.*
Michele Simionato
Jul 18 '05 #7
Peter Otten wrote:
As soon as a test() method without the super(...).test() is reached, no
further test methods will be invoked. Only the first in the list of base
classes will be invoked. If I'm getting it right you have to do something
like:

class Base(object):
def test(self):
print "base"

class D1(Base):
def test(self):
super(D1, self).test()
print "derived 1"

class D2(Base):
def test(self):
super(D2, self).test()
print "derived 2"

class All(D1, D2):
pass

All().test()

Ok, this produces almost what the original poster wanted. You
just have to invert the order of the base classes in All:
class All(D2, D1): .... pass
....

then you will get: All().test()

base
derived 1
derived 2

However, I don't understand jet why this doesn't print:

base
derived 1
base
derived 2

The method test of Base is called just once? Why?
I taught it was something like:

All.test() -> D1.test() + D2.test()

which is the same as:

(Base.test() + print "derived 1") + (Base.test() + print derived 2")

Thanks in advanced,
Josef
Jul 18 '05 #8
Josef Meile wrote:
Peter Otten wrote:
> As soon as a test() method without the super(...).test() is reached, no
> further test methods will be invoked. Only the first in the list of
> base classes will be invoked. If I'm getting it right you have to do
> something like:
>
> class Base(object):
> def test(self):
> print "base"
>
> class D1(Base):
> def test(self):
> super(D1, self).test()
> print "derived 1"
>
> class D2(Base):
> def test(self):
> super(D2, self).test()
> print "derived 2"
>
> class All(D1, D2):
> pass
>
> All().test()

Ok, this produces almost what the original poster wanted. You
just have to invert the order of the base classes in All:
>>>class All(D2, D1): ... pass
...

then you will get: >>> All().test()

base
derived 1
derived 2

However, I don't understand jet why this doesn't print:

base
derived 1
base
derived 2

The method test of Base is called just once? Why?
I taught it was something like:

All.test() -> D1.test() + D2.test()

which is the same as:

(Base.test() + print "derived 1") + (Base.test() + print derived 2")

Thanks in advanced,
Josef


Every instance has just one __dict__, so calling the same Base method twice
would at best be redundant. The Python designers are a bit smarter than
that and implemented "cooperative" methods for newstyle classes. See
http://www.python.org/2.2/descrintro.html#cooperation for the details.

Peter

Jul 18 '05 #9
"Nicolas Lehuen" <ni************@thecrmcompany.com> wrote in message news:<40***********************@news.easynet.fr>.. .

In this case, T.__init__ is not called, because list.__init__ does not use
super(). The only clean way to proceed is to change the inheritance order :
TL(T,list). This way, both constructors are called.


I'm surprised that a built-in type doesn't work with super(). Was
this a design decision, and if so why, or is this something that
should be fixed?
Jul 18 '05 #10
Hi Nicolas

Another related idea:
Use template functions when you have enough control over the objects:

def A(base=object):
class A(base):
def __init__(self):
print "A"
super(A, self).__init__()
return A

def B(base=object):
class B(base):
def __init__(self):
print "B"
super(B, self).__init__()
return B

class C(B(A())):
def __init__(self):
print "C"
super(C, self).__init__()

C()

This is a bit different to multiple inheritance, but can have nice
effects...

David

Nicolas Lehuen wrote:
Ah, so there *is* more than one way to do it, then ? ;)

What the example shows is that super(...).__init__ does make one call to
each superclass' __init__, provided that those superclasses play nicely and
use super() themselves (as Peter wrote). If one of the superclasses does not
use super(), the 'magical' iteration over parent methods is interrupted,
hence the need to put those bad guys at the end of the superclasses list in
the class declaration.

But you're right, David, the simplest way to get what I want is to
explicitely call the superclasses' __init__. However, this would mean that
super() is not as useful as it seems. I'd rather find a way to *always* use
super() than have special cases for certain inheritance trees. In other
words, I'd rather have only one way to do it :).

Regards,
Nicolas

"David Fraser" <da****@sjsoft.com> a écrit dans le message de
news:c6**********@ctb-nnrp2.saix.net...
super is not going to be helpful here, so why not call the X.__init__
functions explicitly?
Since you *need* multiple __init__ calls from the multiply-inherited
class, super isn't going to work...

Nicolas Lehuen wrote:
The only problem I have is that I want to build a multiple inheritance
involving an object which does not cooperate, namely :

class T(object):
def __init__(self):
super(T,self).__init__()

class TL(list,object):
def __init__(self)
super(TL,self).__init__()

In this case, T.__init__ is not called, because list.__init__ does not
use
super(). The only clean way to proceed is to change the inheritance
order :
TL(T,list). This way, both constructors are called.

Here is another example which exhibits the behaviour :

class A(object):
def __init__(self):
super(A,self).__init__()
print 'A'

class B(object):
def __init__(self):
print 'B'

class C(B,A):
def __init__(self):
super(C,self).__init__()
print 'C'

class D(A,B):
def __init__(self):
super(D,self).__init__()
print 'D'

>>C()

B
C
<__main__.C object at 0x008F3D70>

>>D()

B
A
D
<__main__.D object at 0x008F39F0>

The problem is that if you go further down the inheritance, the
behaviour is
even more complicated :

class E(object):
def __init__(self):
super(E,self).__init__()
print 'E'

class F(C,E):
def __init__(self):
super(F,self).__init__()
print 'F'

class G(D,E):
def __init__(self):
super(G,self).__init__()
print 'G'

>>F()

B
C
F
<__main__.F object at 0x008F3D70>

>>G()

B
A
D
G
<__main__.G object at 0x008F3EF0>

class H(E,C):
def __init__(self):
super(H,self).__init__()
print 'H'

class I(E,D):
def __init__(self):
super(I,self).__init__()
print 'I'

>>H()

B
C
E
H
<__main__.H object at 0x008F3E30>

>>I()

B
A
D
E
I
<__main__.I object at 0x008F3FD0>

So the conclusion is : never do that :). Another more constructive
conclusion would be : always put the most cooperative classes first in
the
inheritance declaration, provided that it doesn't interfere with your
needs.
A class which has an uncooperative ancestor is less cooperative than a
class
which has only cooperative ancestors.

Regards,
Nicolas

"Nicolas Lehuen" <ni************@thecrmcompany.com> a écrit dans le
message
de news:40***********************@news.easynet.fr...
OK, I get it now, thanks.

super() method calls should only be used for method involved in
diamond-shaped inheritance. This is logical since in this case the base
classe (from which the diamond-shaped inheritance starts) defines the
interface of the method.

This solves another question I was asking myself about super() : "how
can
it
work when the method signature differ between B and C ?". Answer : the
method signature should not change because polymorphic calls would be
greatly endangered. The base class defines the signature of the method

which
must be followed by all its children, this way super() can work
properly.
The base method signature is not enforced by Python, of course, but
you'd
better respect it unless you get weird result in polymorphic calls.

Regards,
Nicolas

"Peter Otten" <__*******@web.de> a écrit dans le message de
news:c6*************@news.t-online.com...
>Nicolas Lehuen wrote:
>
>
>
>>Hi,
>>
>>I hope this is not a FAQ, but I have trouble understanding the

behaviour
>>of the super() built-in function. I've read the excellent book 'Python

in
>>a Nutshell' which explains this built-in function on pages 89-90.

Based
on
>>the example on page 90, I wrote this test code :
>>
>>class A(object):
>> def test(self):
>> print 'A'
>>
>>class B(object):
>> def test(self):
>> print 'B'
>>
>>class C(A,B):
>> def test(self):
>> super(C,self).test()
>> print 'C'
>>
>>print C.__mro__
>>c=C()
>>c.test()
>>
>>The output is :
>>(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>,

<type
>>'object'>)
>>A
>>C
>>
>>Whereas I was expecting :
>>(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>,

<type
>>'object'>)
>>A
>>B
>>C
>>
>>Was I wrong to expect this (based on what I've read ?)
>
>As soon as a test() method without the super(...).test() is reached, no
>further test methods will be invoked. Only the first in the list of
base
classes will be invoked. If I'm getting it right you have to do

something
>like:
>
>class Base(object):
> def test(self):
> print "base"
>
>class D1(Base):
> def test(self):
> super(D1, self).test()
> print "derived 1"
>
>class D2(Base):
> def test(self):
> super(D2, self).test()
> print "derived 2"
>
>class All(D1, D2):
> pass
>
>All().test()
>
>Here all cooperating methods have a super() call, and the base class

acts
as
>a showstopper to prevent that Python tries to invoke the non-existent
>object.test().
>
>Peter
>
>
>


Jul 18 '05 #11
Duh, so it was a FAQ...

What's interesting in your post is the fact that super is in fact a class
(not a builtin function), and that you can inherit from it to get the
expected behaviour :

http://groups.google.it/groups?hl=it...mp.lang.python

Maybe this should be the default behaviour ?

Regards,
Nicolas

"Michele Simionato" <mi***************@poste.it> a écrit dans le message de
news:95**************************@posting.google.c om...
"Nicolas Lehuen" <ni************@thecrmcompany.com> wrote in message news:<40***********************@news.easynet.fr>.. .
Hi,

I hope this is not a FAQ, but I have trouble understanding the behaviour of the super() built-in function.


Maybe this thread on super will interest you:

http://groups.google.it/groups?hl=it....lang.python.*

Michele Simionato

Jul 18 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Michele Simionato | last post by:
So far, I have not installed Prothon, nor I have experience with Io, Self or other prototype-based languages. Still, from the discussion on the mailing list, I have got the strong impression that...
1
by: Rajorshi | last post by:
Hi, I have two classes, say, Base1 and Base2. Now Derv is a class derived from both like class Derv(Base1,Base2)..... In the destructor of the derived class, if I write something like this def...
9
by: corey.coughlin | last post by:
Alright, so I've been following some of the arguments about enhancing parallelism in python, and I've kind of been struck by how hard things still are. It seems like what we really need is a more...
7
by: Kent Johnson | last post by:
Are there any best practice guidelines for when to use super(Class, self).__init__() vs Base.__init__(self) to call a base class __init__()? The super() method only works correctly in multiple...
0
by: Kurt B. Kaiser | last post by:
Patch / Bug Summary ___________________ Patches : 422 open ( +2) / 3415 closed ( +5) / 3837 total ( +7) Bugs : 933 open (+18) / 6212 closed (+26) / 7145 total (+44) RFE : 237 open...
6
by: Osiris | last post by:
Is the following intuitively feasible in Python: I have an array (I come from C) of identical objects, called sections. These sections have some feature, say a length, measured in mm, which is...
15
by: John Nagle | last post by:
I've been installing Python and its supporting packages on a dedicated server with Fedora Core 6 for about a day now. This is a standard dedicated rackmount server in a colocation facility,...
0
by: IT Recruiter | last post by:
About Me: I am an IT Resourcing Consultant providing unique staffing services to my client based in London. I am looking for a superstar using his web development skills to manage and improve the...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.