Home > Net >  Is it possible to call function from second class with same name in multiple inheritance
Is it possible to call function from second class with same name in multiple inheritance

Time:02-02

Lets say we have three classes

class Father:
    def __init__(self, father_name) -> None:
        self.father_name = father_name

    def name(self):
        print(f"Father name : {self.father_name}")

class Mother:
    def __init__(self, mother_name) -> None:
        self.mother_name = mother_name

    def name(self):
        print(f"Mother name : {self.mother_name}")

class Son(Father, Mother):
    def __init__(self, father_name, mother_name):
        Father.__init__(self, father_name)
        Mother.__init__(self, mother_name)

me = Son('Jamie', 'Jack', 'Linda')
me.name()

The output is :

Father name : Jack

How do I call name method from Mother class instead of Father class without changing the function name so the output would be :

Mother name : Linda

CodePudding user response:

There is a bunch of problems in your code.

  • Your example is not working.
  • Instead of:
    Father.__init__(self, father_name)
    Mother.__init__(self, mother_name)

You should use:

    super(Father, self).__init__(self, father_name)
    super(Mother, self).__init__(self, mother_name)

(Assuming you really want to have inheritance here)

  • Father's name method is called because of something called MRO (method resolution order). Worth a read, but not something you should try to modify. If you only ever want to call Mother's name and not Father's, it's a simple matter of saying Son(Mother, Father) instead of Son(Father, Mother)

  • As mentioned by @Mark, this is not a reasonable use case for inheritance. Child has parents, not is parents.

All in all, if you want to do it with inheritance, that's what I'd suggest:

class Son(Mother, Father):
    def __init__(self, father_name, mother_name):
        super(Father, self).__init__(self, father_name)
        super(Mother, self).__init__(self, mother_name)
    def name(self, ParentClass):
        return super(ParentClass, self).name()

me = Son('Jack', 'Linda')
me.name(Mother)
me.name(Father)

But, I think a much more reasonable way is using attributes.

class Son():
    def __init__(self, father_name, mother_name):
        self.father = Father(father_name)
        self.mother = Mother(mother_name)

me = Son('Jack', 'Linda')
me.mother.name()
me.father.name()

Or, even better, create a Son with already existing Parent objects. That way you can create multiple people with same parents.

class Son():
    def __init__(self, father, mother):
        self.father = father
        self.mother = mother

mother = Mother('Linda')
father = Father('Jack')

me = Son(mother, father)
me.mother.name()
me.father.name()

CodePudding user response:

You should not do something which looks like this as it's even naturally looks bad.

There is MRO (Method Resolution Order) concept in Python, and if you wan't to dig into multiple inheritance, you should read about that.

Answer to your question is just swap Father and Mother mixins

class Son(Mother, Father):
    def __init__(self, my_name, father_name, mother_name):
        self.my_name = my_name            
        Father.__init__(self, father_name)
        Mother.__init__(self, mother_name)

Avoid using raw usage of Class.__init__ though. __init__ is not object creation, but instance fields initialization and might result in unexpected results.

  •  Tags:  
  • Related