We can also add additional methods to our classes. These methods are used either to modify the attributes of the class or to perform actions based on the attributes stored in the class. Finally, we can even use those methods to perform actions on data provided as arguments. In essence, the sky is the limit with methods in classes, so we’ll be able to do just about anything we need to do in these methods.
As with attributes, there are class and instance methods. Class methods have access to their parameters and class attributes, which the access via the syntax class_name.attribute_name. Instance methods by convention have their first parameter as
self and have access to their parameters, class attributes and their instance attributes (self.attribute_name). Class methods are underlined on the UML diagram.
Adding Instance Methods
To add a method to our class, we can simply add a method declaration inside of our class declaration. So, let’s add the methods we need to our
class Student: def __init__(self): self.name = "name" self.age = 19 self.student_id = "123456987" self.credits = 0 self.gpa = 0.0 def birthday(self): self.age += 1 def grade(self, credits, grade_points): current_points = round(self.gpa * self.credits) self.credits += credits current_points += grade_points self.gpa = current_points / self.credits
birthday() method is pretty straightforward. When that method is called, we simply increase the age of this student by 1 year. However, since this an instance method, we need to add a parameter to the function at the very beginning of our list of parameters, typically named
self. This parameter is automatically added by Python whenever we call an instance method, and it is a reference to the current instance on which the method is being called. We’ll learn more about this later.
Therefore, instead of referencing the
age variable directly, we are using
self.age to access the attribute
age in the current instance of the class. Whenever we want to access an attribute of an instance in the definition of a class, we must use the variable
self (or whatever is the first argument of the method) and a dot in front of it; otherwise, Python may complain that the attribute is not defined or behave in unexpected ways.
grade() method is a bit more complex. As parameters, it accepts a reference to the current instance named
self, a number of credits, and the grade points earned for a class; it then must update the
gpa attributes based on that new information. To do this, it must first calculate the current number of grade points the student has earned based on the current GPA, then update those values and recalculate the GPA.
So, in short, whenever we create an instance method while defining a class in Python, we’ll always need to remember to add an extra parameter—conventionally named
self—to the beginning of our list of parameters so that we can always have a reference to the current instance of the class.
Note, no argument is passed for the
self parameter when calling an instance method. To add a grade to the Student object
Bob, the syntax for calling
Adding Class methods
Let’s add some class methods. In the class
Main, we note that it has a class-attribute
students which is a list of
Student objects. We’ll add a
main method, create a student and add it to the list of students.
from Student import * class Main: students =  teachers =  @classmethod def main(cls, args): student1 = Student() cls.students.append(student1) # change name cls.students.name = "Mari" print(cls.students.name) #cls.students - a list of student-objects #cls.students - a student-object stored at index 0 #cls.students.name - the name attribute of a student-object stored at index 0
Here we create a student-object, add it to the class-list of students by using
cls.students, then change its name.
We’ve already discussed variable scope earlier in this course. Recall that two different functions may use the same local variable names without affecting each other because they are in different scopes.
The same applies to classes. A class may have an attribute named
age, but a method inside of the class may also use a local variable named
age. Therefore, we must be careful to make sure that we access the correct variable, using the
self reference if we intend to access the attribute’s value in the current instance. Here’s a short example:
class Test: age = 15 def foo(self): age = 12 print(age) # 12 print(self.age) # 15 def bar(self): print(self.age) # 15 print(age) # NameError
As we can see, in the method
foo() we must be careful to use
self.age to refer to the attribute, since there is another variable named
age declared in that method. However, in the method
bar() we see that
age itself causes a
NameError since there is no other variable named
age defined in that scope. We have to use
self.age to reference the attribute.
So, we should always get in the habit of using
self to refer to any attributes, just to avoid any unintended problems later on.
Let’s go ahead and add the
promotion() method to the
Teacher class as well. That method should accept a single integer as a parameter (along with a parameter named
self as the first parameter, of course), and then add that value to the Teacher’s current salary.
Use the first test below to check that we’ve included the correct methods in the
Teacher classes and
Main. Then, use the second test to confirm that those methods work correctly. Each test below is worth 5 points in this module, for a total of 10 points.
This content is presented in the course directly through Codio. Any references to interactive portions are only relevant for that interface. This content is included here as reference only.