I have a child class named USA and it has two parent classes, A and B.
Both parents have a method named change_to_4 and in B.__init__ I call the method, but instead of using the method that I defined in B it uses the A definition of the change_to_4 method.
class A:
def __init__(self) -> None:
self.a = 1
super().__init__()
def change_to_4(self):
self.x = 4
class B:
def __init__(self) -> None:
self.b = 2
self.change_to_4()
super().__init__()
def change_to_4(self):
self.b = 4
class USA(A, B):
def __init__(self) -> None:
super().__init__()
print(f"A vars = {vars(A())}")
print(f"B vars = {vars(B())}")
print(f"USA vars = {vars(USA())}")
print(f"USA mro -> {USA.__mro__}")
I expect something like this:
A vars = {'a': 1}
B vars = {'b': 4}
USA vars = {'a': 1, 'b': 4}
USA mro -> (<class '__main__.USA'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
But the output is
A vars = {'a': 1}
B vars = {'b': 4}
USA vars = {'a': 1, 'b': 2, 'x': 4}
USA mro -> (<class '__main__.USA'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
When the interpreter looks up an attribute of an instance, in this case
self.change_to_4on an instance ofUSA, it first tries to find'change_to_4'inself.__dict__, and failing to find it there, the interpreter then follows the method resolution order ofUSA(USA,A,B,objectas shown in the output) to find thechange_to_4attribute in the first base class that has it defined.Excerpt from the documentation of Custom classes:
In this case,
Ais the first base class ofUSAthat defineschange_to_4, soself.change_to_4()gets translated toA.change_to_4(self), resulting inself.x = 4getting executed.That the call
self.change_to_4()is made from a method inBdoes not change the fact thatAcomes beforeBin the method resolution order of aUSAinstance.