Mark D
Mark D

Reputation: 75

Inheritance troubles. - Python

Someone had this exact same problem on this site, but the answer didn't relate to the part I have trouble with.
Inheritance - Method Calls

Consider the following class definitions.

class C1(object):
    def f(self):
        return 2*self.g()

    def g(self):
        return 2

class C2(C1):
    def f(self):
        return 3*self.g()


class C3(C1):
    def g(self):
        return 5

class C4(C3):
    def f(self):
        return 7*self.g()

obj1 = C1()
obj2 = C2()
obj3 = C3()
obj4 = C4()

For this problem you are to consider which methods are called when the f method is called. So for example, when obj1.f() is called, the f method of C1 is called which calls the g method of C1. This could be represented as a 'calling list' of the form

['C1.f', 'C1.g'] 

Write three assignment statements that, respectively, assigns the 'calling list' for obj2.f() to the variable obj2_calls, assigns the 'calling list' for obj3.f() to the variable obj3_calls and assigns the 'calling list' for obj4.f() to the variable obj4_calls.

I have no problem understanding the first assignment, it is obj2_calls = ['C2.f', 'C1.g']
but I am wracking my brain trying to figure out the next one. I thought since there is no C3.f that the list would be ['C1.f'] but unfortunately it's not.

Just to clear up, this IS homework

Upvotes: 5

Views: 1657

Answers (2)

mgilson
mgilson

Reputation: 309821

This has to do with the method resolution order (MRO) of your class. (see here for some useful info)

As you stated correctly, there is no C3.f function, so python looks up the f method on the first base-class in the MRO that has f defined. In this case, that is (C1). Now, that method (C1.f) calls self.g(). In this case self is an instance of C3, so of course, self.g calls C3.g since that is the highest g function in the MRO. If you wanted to guarantee that you get C1.g, you'd need to do it explicitly:

class C1(object):
    def f(self):
        return 2*C1.g(self)
    def g(self):
        return 5

which also makes a nice lead-in to talking about double-underscore name mangling. Since that is a separate topic though, maybe it's best to only leave a link to some useful documentation.

Upvotes: 3

A. Rodas
A. Rodas

Reputation: 20679

obj3_calls is ['C1.f', 'C3.g']. As you point out, there is no C3.f in that class, but this method is inherited from C1. This one in turn calls self.g, and since C3.g is defined, it overrides the method that is inherited from C1.

Upvotes: 1

Related Questions