[Tutor] class questions

Hugo Arts hugo.yoshi at gmail.com
Sun Jun 27 13:27:37 CEST 2010


On Sun, Jun 27, 2010 at 2:09 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Sun, 27 Jun 2010 03:05:16 am Payal wrote:
>>
>> Can you give any simple example where this simple mro will work
>> incorrectly?
>
> Probably not... it's quite complicated, which is why it's rare. I'll
> have a think about it and see what I can come up with.
>

Here's my attempt. Consider this simple Diamond hierarchy:

class A:
    def x(self): return "in A"

class B(A): pass
class C(A):
    def x(self): return "in C"

class D(B, C): pass

   A
  / \
 /   \
B   C
 \    /
  \  /
   D

Now, with this diagram the following code probably doesn't do what you expect:

>>> obj = D()
>>> obj.x()
'in A'

D inherits from C, which overrides the x method. But this is seemingly
completely ignored by python, which produces the A.x method! So why
does this happen?

well, the old MRO uses a simple depth-first, left-to-right search.
This means that to find a method, python first looks into the leftmost
parent, then its leftmost parent, et cetera et cetera. For our
diamond, that means this MRO:

D, B, A, C, A

so, when you try to access D.x, it will look first in D (not found), B
(not found), then A, producing the A.x method. And this probably isn't
what you want (we inherited from C for a reason, you know).

For new style classes, the MRO is actually D, B, C, A. That produces
the correct results. The algorithm is a little complicated, and if you
would like to know, the link you posted earlier has all the details.

Hugo


More information about the Tutor mailing list