You have a valuable problem on your hands.
This question is what we call the diamond problem and it occurs in multiple inheritance when a class inherits from two classes that inherit from the same class.
Andtheproblemisjustthis:shouldtheattributesofAbepassedtoDthroughBorC?Theycannotduplicatethem,otherwisetheywouldbeduplicated.Inyourcase,youhavetheatributo1
fieldinW
.Whatshouldbethefinalvalueofatributo1
,whatdoIpassthroughtheX
classortheY
class?
Theproblemgetsevenworsebecauseyoumisusedthesuper
function.Thisispossiblybecauseyoudonotquiteunderstandwhatitdoes.
In your case, the Z
class does not have an initializer method ( __init__
) and the MRO defines that the method name will be solved first in X
. Remember that we are working with an instance of Z
. So the X.__init__
method will run first.
The X.__init__
method calls the super
function, which returns a proxy object for the next class in the sequence defined by the MRO of our instance. Since we work as an instance of Z
and we are in the X
class, the next class in the sequence defined by the MRO will be Y
. That is, when you do super().__init__(atributo1)
to X
, you will call the Y
initializer. WTF?
Notice the confusion? A% class of% that inherits only from X
is invoking a method in W
. But calm, it's not the seven-headed bug (but it's multi-headed: D).
If you read the documentation for the Y
function, which I believe you have already read , you will see that it works well with multiple inheritance when all classes have the same signature. But how do you have the same signature if each class demands different parameters? There you are, as the developer and author of the project, that should define what should be done or not. Make analysis of the consequences. One way is to use the wildcard parameter super
and use only named parameters. Something like:
class W:
def __init__(self, **kwargs):
self.atributo1 = kwargs['atributo1']
def metodo1(self):
print("Metodo1")
class X(W):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.atributo2 = kwargs['atributo2']
class Y(W):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.atributo3 = kwargs['atributo3']
So all classes will have the same signature on their initializers and you can do:
z = Z(atributo1=1, atributo2=2, atributo3=3)
print('Atributo 1:', z.atributo1)
print('Atributo 2:', z.atributo2)
print('Atributo 3:', z.atributo3)
Getting:
Atributo 1: 1
Atributo 2: 2
Atributo 3: 3