Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 665
Mark D Avatar asked Oct 05 '22 08:10

Mark D


2 Answers

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.

like image 135
mgilson Avatar answered Oct 23 '22 01:10

mgilson


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.

like image 36
A. Rodas Avatar answered Oct 23 '22 00:10

A. Rodas