0

Consider Python multiple inheritance:

class A(object):
    def __init__(self):
        self.name = 'a'
    def y(self):
        return "A"

class B(A):
    def __init__(self):
        A.__init__(self)
        self.name = 'b'
    def y(self):
        return "B"

class C(object):
    def __init__(self):
        self.name = 'c'
    def y(self):
        return "C"

class D(C, B):
    def __init__(self):
        C.__init__(self)
        B.__init__(self)

When creating an instance of D it can be seen that as Python goes through each constructor it reassigns self.name and therefore the value of self.name is, as expected, the last value assigned to it:

>>> foo = D()
>>> print(foo.name)
b

However, for the method y() it seems that the method assigned is the first method assigned to it:

>>> print(foo.y())
C

Why the discrepancy between which attributes are assigned? What are the rules? The Python manual in fact has a section on multiple inheritance, however I don't see this topic mentioned there.

Note that this question is not homework, but it is adapted from a lesson in the wonderful Introduction to Computer Science and Programming Using Python course.

dotancohen
  • 30,064
  • 36
  • 138
  • 197
  • Why would you expect any different? `C.y` doesn't call any of the parent class methods, unlike `C.__init__`. – jonrsharpe Jul 29 '14 at 16:53
  • @jonrsharpe: `B.y()` is defined after `C.y()`, so I would expect that the definition of `B.y()` would have replaced the definition of `C.y()`. This would be much in the same sense as B()'s `self.name` replaces the value of C's `self.name`. – dotancohen Jul 29 '14 at 16:59
  • No, that's not how it works. `D` inherits `y` from `C`, as that's the first parent to define it. The attribute is different as you're explicitly calling through the various different `__init__`s. If e.g. `C.y` called `B.y`, things would be different. – jonrsharpe Jul 29 '14 at 17:01
  • You **explicitly** call parent methods in `D.__init__`, while you do no such thing in `y`. There is no other difference here. – Martijn Pieters Jul 29 '14 at 17:03
  • 1
    If you want to understand how Python multiple inheritance works, you'll need to read about the Method Resolution Order: https://www.python.org/download/releases/2.3/mro/. Check out what `D.__mro__` is set to to understand what `y` is picked. – Martijn Pieters Jul 29 '14 at 17:04
  • @MartijnPieters: Thank you, it appears that the answer to the question will be in that page. I read only up to the phallus just now, but I'll be sure to go over it again (and probably again). You can go ahead and post that link (or a quote from the appropriate part of it) as an answer and I'll accept it. Thank you! – dotancohen Jul 29 '14 at 17:10
  • Your question is really a duplicate then; closed as such. – Martijn Pieters Jul 29 '14 at 17:22
  • Thank you Martin. I did review the question linked, but I discounted is as I am not using super() and I did not know enough at the time to generalize the content there. In the interest of helping people searching for information in the future, I would recommend either editing that question to be more general (i.e. not mention `super()` explicitly) or to reopen this question as the general case. – dotancohen Jul 29 '14 at 17:34

0 Answers0