mi

  • Thread starter Eric J. Van der Velden
  • Start date
E

Eric J. Van der Velden

Hello,

I have these types,

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

If I do (in 3.1)A
C
B
D

Why this order? I thought, first to D, then B, then A. He prints "A".
He comes back in B and prints "B". He goes to C. Then somehow he
doesn't go again to A. He prints "C". Then back to D and prints "D".

Thanks,

Eric J.
 
T

Thomas Jollans

Hello,

I have these types,

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

If I do (in 3.1)


A
C
B
D

Why this order? I thought, first to D, then B, then A. He prints "A".
He comes back in B and prints "B". He goes to C. Then somehow he
doesn't go again to A. He prints "C". Then back to D and prints "D".

Think again about what you're seeing here. You're printing AFTER the call to
super().__init__(). That means that it first walks the inheritance hierarchy,
and then prints -- your trace is "the wrong way around"

So, what happens is: you call D(). In it, super() delegates to B(). Which has
super delegate to C(), which then has super() delegate finally to A().

D, B, C, A

You say you were expecting D, B, A -- but what of C? You also imply that you
would have expected two visits to A -- but that would defeat the point of
super() -- you don't actually want one constructor to be called twice: the
constructor almost certainly isn't written with that possibility in mind.
 
C

Chris Rebert

Hello,

I have these types,

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

If I do (in 3.1)
A
C
B
D

Why this order?

Well, it's clearer for illustration purposes if you do the print()s
"preorder" (before the super calls) rather than "postorder", but
anyway...

Because that's how Python's Method Resolution Order (MRO) works. Very
smart people have thought a lot about this. It is The Right Order
(tm).
To understand *why* it's right, read:
http://www.python.org/download/releases/2.2.3/descrintro/#mro
and (if you dare):
http://www.python.org/download/releases/2.3/mro/

The order (of the method calls, not the print()s) is (extremely
roughly) from most derived to most ancestral, without calling anything
twice. Is that not a logical and sensible (albeit not necessarily
obvious) rule?
I thought, first to D, then B, then A. He prints "A".
He comes back in B and prints "B". He goes to C. Then somehow he
doesn't go again to A. He prints "C". Then back to D and prints "D".

"super()" is a bit of a misnomer. **It doesn't necessarily call a
superclass method.** In fact, the Dylan programming language (which
Python borrowed its MRO from) instead names the analogous function
"next-method" because it calls the method that comes after the current
one in the MRO.

Here's what actually happened: D called B. Then B called *C* (seems
bizarre, yes). C is obviously not a superclass of B; but this is the
only way to make things work out right (see aforelinked docs). From
there, C called A, and the rest is obvious.

Multiple inheritance can get tricky; avoid it when possible.

Cheers,
Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,787
Messages
2,569,631
Members
45,338
Latest member
41Pearline46

Latest Threads

Top