Why do I get an error for incorrect number of arguments?
Question: I have:

    
    
    import datetime
    class Animal(object):
    
        def __init__(self, dob, carnivore):
            self.__dob = dob
            self.__carnivore = carnivore
    
        @property
        def dob(self):
            return self.__dob
    
        @dob.setter
        def dob(self, dob):
            self.__dob = dob
    
        @property
        def carnivore(self):
            return self.__carnivore
    
        @carnivore.setter
        def carnivore(self, carnivore):
            self.__carnivore = carnivore
    
        def __str__(self):
            return "DOB: " + str(self.__dob) + "\nCarnivore: " + str(self.__carnivore)
    

My second class:

    
    
    import Species.Animal as Animal
    import datetime as date
    
    
    class Amphibian(Animal):
    
        def __init__(self, dob=date.datetime.now(), carnivore=False, *characteristics):
            super(Animal, self).__init__(dob, carnivore)
            self.__characteristics = []
            for characteristic in characteristics:
                self.__characteristics.append(characteristic)
    
        @property
        def characteristics(self):
            return self.__characteristics
    
        @characteristics.setter
        def characteristics(self, characteristic):
            self.__characteristics.append(characteristic)
    
        def __str__(self):
            characteristics = ""
            for characteristic in self.__characteristics:
                characteristics += str(characteristic)
            return characteristics
    

Using:

    
    
    amphibian = Amphibian(date.date(1979, 1, 12), True, "BackBone", "Cold Blooded")
    print(amphibian)
    

I get the error:

> Traceback (most recent call last): File
> "C:/Users/Daniel/PycharmProjects/ObjectOrientedSpecies/Species/Amphibian.py",
> line 7, in class Amphibian(Animal): TypeError: module.__init__() takes at
> most 2 arguments (3 given)

I am new to Python so I'm not sure what good OO Practices are.


Answer: There are two issues I can see. Firstly you should call `super` on the class
name of the class you are calling `super` in (that is a bit of a mouthful) so
that line should be `super(Amphibian, self).__init__(dob, carnivore)` and
_not_ `super(Animal, self).__init__(dob, carnivore)`. Python will find the
baseclass `Animal` itself.

However the main problem is that the class `Animal` is (almost certainly) in a
file called "Animal.py". Python makes a module called `Animal` automagically
when it sees a file called "Animal.py" (and does something similar for all
other ".py" names. So your class `Animal` is, in fact inside a module called
`Animal`.

Therefore when you do `import Species.Animal as Animal` you are importing the
_module_ not the class inside it. So when you do `class Amphibian(Animal):`
your Amphibians are inheriting from the class `module` not from the class
`Animal`. You need to change your import to the following to get the class
`Animal` instead: `from Species.Animal import Animal`.

In terms of your style I don't really see the point of having lots of
decorated getters and setters if there is nothing going on inside them except
simple getting and setting. Just get rid of the underscores in front of the
atribute names and use them directly. You only need to use the getters and
setters if something else has to happen to do the getting and setting.

