Home > Enterprise >  Class inheritance and importing -- python
Class inheritance and importing -- python

Time:04-10

This may be a little lengthy but I am at a loss with importing my parent and child class.

I have a feeling I am getting my capitalization incorrect when applying the class names. I am getting the error:

TypeError: Student.__init__() missing 2 required positional arguments: 'age' and 'major'

Any help is much appreciated.

StudentAdder.py (Main)

import pickle
from sre_constants import SUCCESS
from tkinter import *
from tkinter import messagebox
from student import Student
from person import Person

#main method
def main():

    studentList = []
    #load the list from a pickle file
    with open("student.pickle", "rb") as f:
        studentList = pickle.load(f)

    #addStudent method to append Input to list
    def addStudent():
        name = "name"
        age = "age"
        major = "major"
        name = nameInput.get()
        age = ageInput.get()
        major = majorInput.get()
        studentList.append(Student(name, age, major))
        #save list to pickle file
        with open("student.pickle", "wb") as f:
            pickle.dump(studentList, f)

    #displays a success message upon adding a student
    def onClick():
        messagebox.showinfo("SUCCESS", "Student Added!")

    #create a GUI
    window = Tk()
    window.title("Add a Student")
    window.geometry("325x175")
  
    #create labels and text boxes for each value
    nameLabel = Label(window, text="Name:")
    ageLabel = Label(window, text="Age:")
    majorLabel = Label(window, text="Major:")

    nameInput = StringVar()
    ageInput = StringVar()
    majorInput = StringVar()

    #create grid for labels
    nameLabel.grid(row=0, column=0)
    ageLabel.grid(row=1, column=0)
    majorLabel.grid(row=2, column=0)

    #create input boxes for each value
    nameInput = Entry(window, width = 25)
    ageInput = Entry(window, width = 25)
    majorInput = Entry(window, width = 25)

    #create grid for input boxes
    nameInput.grid(row=0, column=1)
    ageInput.grid(row=1, column=1)
    majorInput.grid(row=2, column=1)

    #create a save button to save the student -- binds commands to button
    saveButton = Button(window, text="Save", command= lambda: [addStudent(), onClick()])
    saveButton.grid(row=3, column=1)

    #create quit button
    quitButton = Button(window, text="Quit", command= window.destroy)
    quitButton.grid(row=4, column=1)

    #start the GUI
    window.mainloop()

    #print the list
    print()
    for student in studentList:
        print(student)

    print()

main()

person.py (Parent Class)

#create a parent class
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def getName(self):
        return self.name

    def getAge(self):
        return self.age

    def setName(self, name):
        self.name = name

    def setAge(self, age):
        self.age = age

    def __str__(self):
        return "Person: "   self.name   " "   str(self.age)

student.py (Child Class)

from person import Person

class Student(Person):
    def __init__(self, name, age, major):
        Student(Person).__init__(self, name, age, major)
        self.name = name
        self.age = age
        self.major = major

    def getMajor(self):
        return self.major

    def setMajor(self, major):
        self.major = major

    def __str__(self):
        return "Student: "   self.name   \
            ", Age: "   str(self.age)   \
            ", Major: "   self.major

CodePudding user response:

It looks like your mistake is this line in student.py:

Student(Person).__init__(self, name, age, major)

The code Student(Person) is trying to make a new instance of Student, but you are only passing one argument (Person) instead of the required three (name, age and major). That is why you see missing 2 required positional arguments: 'age' and 'major' in your error message.

However, it looks like you are actually trying to call the __init__ method of the parent class. You would do that like this:

super().__init__(name, age)

Note that I did not specify the major argument, as the Person class does not accept this as a parameter. Also, the __init__ method of the Person class already stores the name and age parameters, so you don't need to do that in Student.__init__. So you can change Student.__init__ to be the following:

class Student(Person):
    def __init__(self, name, age, major):
        super().__init__(name, age)
        self.major = major

Alternatively, if you don't want to depend on Person.__init__, you can leave out the super() call and set all the attributes yourself:

class Student(Person):
    def __init__(self, name, age, major):
        self.name = name
        self.age = age
        self.major = major
  • Related