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
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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With