for my class I'm creating a program that allows a user to enter their info and how many classes they want to take, then will ask for the course information, that then will output their info, a list of their courses, and a Final GPA. This is only a chunk of my code. When I was getting help from my TA, he initially had me put the letter grade to GPA dictionary and the empty course list within the constructor/init method, but when I starting to polish up the code today, I questioned why he did that, and discovered that it didn't matter if I put the dictionary and the empty course list as a class attribute or within the constructor, my code works all the same.
I'm confused because in the examples of class attributes my professor showed us, they were all statements like race_distance = 3.0, and he told us class attributes are the same for each instance of a class, and instance attributes are things generated each time a new instance is created and can be changed to reflect the instance. Every student will have the same letter grade to Gpa standard applied to them, and every student will start out with an empty list, but not every student will have the same list of courses. Why does the code work regardless of where I put these variables/attributes? I settled upon believing the dictionary was a class attribute and the empty course list was an instance attribute, because the dictionary will not change, but the empty course list will eventually become filled with courses depending on what the student takes. Am I correct in this thinking? I mean, hey, if it works, it works, but I've been having trouble understanding the logic behind classes and I wanted to make sure I got it right. I can show the rest of my code if it's helpful. Thanks.
class Student:
letterGradeToGpaDictionary = {'A+': 4.0, 'A': 4.0, 'A-': 3.7,
'B+': 3.3, 'B': 3.0, 'B-': 2.7,
'C+': 2.3, 'C': 2.0, 'C-': 1.7,
'D+': 1.3, 'D': 1.0}
def __init__(self, fullName, email, major, projectInfo):
"""
:param fullName: The student's full name
:param email: The student's email address
:param major: The student's major
:param projectInfo: a description of the project
"""
self.fullName = fullName
self.email = email
self.major = major
self.projectInfo = projectInfo
self.courses = []
Edit: in the answers stackoverflow referred me to, most answers demonstrate class attributes with immutable objects, but a list, a mutable object, worked as a class attribute in my program. The answer that did refer to using mutable objects in a class attribute instead of an instance attribute said this would cause leakage, and I don't know what they mean by that
I tried putting the dictionary and the empty list either before the __init__ method or inside it, and the output remained the same with no errors. Based on what I learned, that class attributes are things that cannot be different based on what instance uses it, and instance attributes are things inside of functions within the constructor that are created for each instance and can be different for each instance, I expected my code to fail when I changed them from instance attributes to class attributes but nothing happened.