On Wed, Aug 11, 2010 at 12:45 PM, Eric J. Van der Velden <ericjvandervel...@gmail.com> wrote: > 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) >>>> d=D() > 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 -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list