0

I just started learning about classes and inheritance in Python 3. I want to print the name of a student, which is inherited from the superclass Person. Unfortunately I keep getting a TypError.

code:

class Person(object):

    def __init__(self, name="Mike", age = 25, place_of_birth="Stockholm"):
        self.age = age
        self.name = name
        self.place_of_birth = place_of_birth


class Student(Person):

    def __init__(self, name, age, university = "University of Stockholm", gpa = 8):
        super().__init__(name, age)
        self.university = university
        self.gpa = gpa

I then like to print the name of the student by calling:

student1 = Student()
print(student1.name)

But I keep getting this error message:

Traceback (most recent call last): TypeError: init() missing 2 required positional arguments: 'name' and 'age'

eppe2000
  • 110
  • 1
  • 1
  • 8
  • You haven't given init name and age, as you declared it. `Student()` won't work because you gave it arguments and you're now calling it without. – pvg Dec 22 '15 at 23:08

2 Answers2

0

The __init__() method of Student takes 2 positional arguments: name and age. You need to specify those arguments when creating a new instance:

student1 = Student('eppe2000', 20)
print(student1.name)

If you instead want the class Student to default to class Person default arguments, in case they have not been specified, you can do it like this:

class Person(object):

    def __init__(self, name="Mike", age=25, place_of_birth="Stockholm"):
        self.age = age
        self.name = name
        self.place_of_birth = place_of_birth


class Student(Person):

    def __init__(self, university="University of Stockholm", gpa=8, **kwargs):
        super().__init__(**kwargs)
        self.university = university
        self.gpa = gpa


>>> s = Student()
>>> s.name
'Mike'

>>> s = Student(name="Daniele")
>>> s.name
'Daniele'

Basically you forward all the keywords arguments that are unknown to the class Student to its parent class. Not that if you specify an invalid keyword (i.e: 'surname') you will get a TypeError because neither Student or Person specify a keyword argument with key 'surname'.

If you need info about **kwargs check this post: https://stackoverflow.com/a/36908/3477005

Community
  • 1
  • 1
Daniele Pantaleone
  • 2,657
  • 22
  • 33
  • Thanks. But what I was trying to accomplish was that every new student object created, inherited the 'name' and 'age' attributes from the Person' class, which are initially set to 'Mike' and 25 – eppe2000 Dec 22 '15 at 23:44
0

If you want Student to always default to the name and age of the Parent class then you don't want Student to take a name and age value.

class Student(Person):
    def __init__(self, university = "University of Stockholm", gpa = 8):
        super().__init__() # runs parent __init__ taking no values
        self.university = university
        self.gpa = gpa

>>> student1 = Student()
>>> student1.name
'Mike'
>>> student1.age
25

When you use super().__init__(name, age) you are wanting to pass the name and age given to the Student class to the Parent class. But since you don't want to pass anything it is getting errors.

Now, if you want the Student class to be able to take values as well as default to the ones provided by the parent class you can do this.

class Student(Person):
    def __init__(self, name = None, age = None, university = "University of Stockholm", gpa = 8):
        if name is None and age is None:
            super().__init__()
        else:
            super().__init__(name, age)
        self.university = university
        self.gpa = gpa

What happens here is if no name or age is provided if name is None and age is None then it defaults to the values from Person class. However if both the name and age are provided, then it will use those values.

>>> student1 = Student()
>>> student1.name
'Mike'
>>> student1.age
25
>>> student2 = Student('Bill', 19)
>>> student2.name
'Bill'
>>> student2.age
19
Steven Summers
  • 5,079
  • 2
  • 20
  • 31