1

I'm pretty new to Python and I'm trying to understand multiple inheritance. Below I have a code, where I need to create an array of Animals.

  • An Animal can be Domesticated and Feline
  • A Tiger is a Feline Animal
  • A Cat is a Domesticated & Feline Animal

Here are the classes:

class Animal:
    def __init__(self, birthDate, type, name, numOfLegs):
        self.birthDate = birthDate
        self.type = type
        self.name = name
        self.numOfLegs = numOfLegs


class Domesticated(Animal):
    def __init__(self, birthDate, type, name, numOfLegs, lastVetCheck):
        super().__init__(birthDate, type, name, numOfLegs)
        self.lastVetCheck = lastVetCheck


class Feline(Animal):
    def __init__(self, birthDate, type, name, numOfLegs, mustacheLength):
        super().__init__(birthDate, type, name, numOfLegs)
        self.mustacheLength = mustacheLength


class Cat(Feline, Domesticated):
    def __init__(self, mustacheLength, numOfLegs, name, type, bDate, vetDate):
        Feline.__init__(self, bDate, type, name, numOfLegs, mustacheLength)
        Domesticated.__init__(self,bDate, type, name, numOfLegs, vetDate)


class Tiger(Feline):
    def __init__(self, birthDate, type, name, numOfLegs, mustacheLength):
        super().__init__(birthDate, type, name, numOfLegs, mustacheLength)

Rese of the code:

animal_array = []
my_cat = Cat('4', '4', 'Tom', 'Mammal', '1.2.3', '3.4.5')
my_animal = Animal('6.7.8', 'Reptile', 'Rafael', '4')
my_tiger = Tiger('1.1.1', 'Mammal', 'Tiger', '4', '9')
animal_array.append(my_cat)
animal_array.append(my_animal)
animal_array.append(my_tiger)

I receive this error:

Traceback (most recent call last):

  File "C:/Users/Name/PycharmProjects/Pandas/test.py", line 33, in <module>
    my_cat = Cat('4', '4', 'abc', 'mammal', '1.2.3', '3.4.5')

  File "C:/Users/Name/PycharmProjects/Pandas/test.py", line 23, in __init__
    Feline.__init__(self, bDate, type, name, numOfLegs, mustacheLength)

  File "C:/Users/Name/PycharmProjects/Pandas/test.py", line 17, in __init__
    super().__init__(birthDate, type, name, numOfLegs)

TypeError: __init__() missing 1 required positional argument: 'lastVetCheck'

Now I'm sure that it's a simple issue, probably my classes structuring is bad, though I have no clue what to fix. I sure can use any structuring tips since I'm pretty new to OO.

2 Answers 2

2

If you design your classes and use super properly, this is a non-issue. Every class (even Animal) should accept arbitrary keyword arguments to pass on to super().__init__. Each class lists the parameter names it will handle without passing upstream explicitly. When you instantiate an object, only use keyword arguments, which you can enforce in Python 3 by making the named parameters keyword-only.

If you define each __init__ correctly, then kwargs should be empty by the time object.__init__ is invoked by one of the calls to super.

class Animal:
    def __init__(self, *, birthDate, type, name, numOfLegs, **kwargs):
        super().__init__(**kwargs)
        self.birthDate = birthDate
        self.type = type
        self.name = name
        self.numOfLegs = numOfLegs


class Domesticated(Animal):
    def __init__(self, *, lastVetCheck, **kwargs):
        super().__init__(**kwargs)
        self.lastVetCheck = lastVetCheck


class Feline(Animal):
    def __init__(self, *, mustacheLength, **kwargs):
        super().__init__(**kwargs)
        self.mustacheLength = mustacheLength


class Cat(Feline, Domesticated):
    pass


class Tiger(Feline):
    pass



animals = [
    Cat(mustacheLength='4', numOfLegs='4', name='Tom', type='Mammal', bDate='1.2.3', vetDate'3.4.5')
    Animal(birthDate='6.7.8', type='Reptile', name='Rafael', numOfLegs'4')
    Tiger(bDate='1.1.1', type='Mammal', name='Tiger', numLegs='4', mustacheLength='9')
]

Note the lack of repetition; nothing common to all animals is repeated in any of the subclasses. The only boilerplate is the identical call to super().__init__(**kwargs) in each class's __init__ method.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes I solved it the same way at the time, that fixes it. thanks!
1

Unfortunetly, you can't use super() like that when you're using multiple inheritance and try to send different arguments to each father class.

If you want to leave the structure of the classes as they are, you need to change the code as follows:

class Animal:
    def __init__(self, birthDate, type, name, numOfLegs):
        self.birthDate = birthDate
        self.type = type
        self.name = name
        self.numOfLegs = numOfLegs


class Domesticated(Animal):
    def __init__(self, birthDate, type, name, numOfLegs, lastVetCheck):
        Animal.__init__(self, birthDate, type, name, numOfLegs)
        self.lastVetCheck = lastVetCheck


class Feline(Animal):
    def __init__(self, birthDate, type, name, numOfLegs, mustacheLength):
        Animal.__init__(self, birthDate, type, name, numOfLegs)
        self.mustacheLength = mustacheLength


class Cat(Feline, Domesticated):
    def __init__(self, mustacheLength, numOfLegs, name, type, bDate, vetDate):
        Feline.__init__(self, bDate, type, name, numOfLegs, mustacheLength)
        Domesticated.__init__(self,bDate, type, name, numOfLegs, vetDate)


class Tiger(Feline):
    def __init__(self, birthDate, type, name, numOfLegs, mustacheLength):
        super().__init__(birthDate, type, name, numOfLegs, mustacheLength)

Example:

my_cat = Cat('4', '4', 'Tom', 'Mammal', '1.2.3', '3.4.5')
print(my_cat.name)

Output:

Tom

2 Comments

You can use super, if you define the classes properly.
Yeah, you're right, I offered this solution if he wants to leave the structure of the classes as they are.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.