I have given a class A
with methods f
and g
. In the implementation of Af
, the method self.g
is called, ie Ag
is used. (I am not able/willing to change this class A
since it comes from a python package.)
Now I want to build a child class B
of A
and want to overwrite the methods f
and g
. In the implementation of Bf
, I call super().f
, ie Af
is used. In the implementation of Bg
, I call self.f
, ie Bf
is used.
I would expect that everything is well defined: Bg
calls Bf
calls Af
calls Ag
In fact, I get a RecursionError
as I am running into an infinite number of recursions: Bg
calls Bf
calls Af
calls Bg
What do I not understand correctly?
Here is a implementation:
class A:
def f(self):
print('Method A.f was called.')
self.g()
def g(self):
print('Method A.g was called.')
class B(A):
def f(self):
print('Method B.f was called.')
super().f()
def g(self):
print('Method B.g was called.')
self.f()
b = B()
b.g()
For clarification: In my application, A
is a scikit-learn class, f
is fit
and g
is fit_transform
. In this scikit-learn class, fit_transform
is explicitly overwritten, and fit
unfortunately uses fit_transform
. To ensure that my child class B
does not inherit fit_transform
from A
, I have to redefine it in the usual way, and this leads to infinite recursion as explained.
The g method of B overwrites the one of A as you said, meaning Af will call Bg, if you change the name of the method Bg your code will run as you expect it to
What do I not understand correctly?
Even though self.g()
was called within Af
, the value that was passed as self
is still an instance of B
, so Bg
is looked up by this operation rather than Ag
.
It would help if you could explain what problem you are trying to solve with this structure. In particular, I don't understand why, for any real-world code, it would be useful within the B class for g
to call upon f
, but in the base class to do it the other way around.
self
is bound to the B
object on which .g()
was called.
Try replacing the inheritance with composition instead:
class A:
def f(self):
print('Method A.f was called.')
self.g()
def g(self):
print('Method A.g was called.')
class B:
def __init__(self, a):
self.a = a
def f(self):
print('Method B.f was called.')
self.a.f()
def g(self):
print('Method B.g was called.')
self.f()
a = A()
b = B(a)
b.g()
Output:
Method B.g was called.
Method B.f was called.
Method A.f was called.
Method A.g was called.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.