Object-Oriented Python

Python classes:

#!/usr/bin/env python3

import sys

class Student:

# these attributes have default values

firstName = “Alice”

middleName = “Barbara”

lastName = “Clark”

studentId = 12357

year = “Senior”

major = “Computer Science”

gpa = 3.3

def printInfo(self):

print(“Name: ” + self.firstName + ” “, end=””)

print(self.middleName + ” “, end=””)

print(self.lastName)

print(“Student ID: ” + str(self.studentId))

print(“Year: ” + self.year)

print(“Major: ” + self.major)

print(“GPA: ” + str(self.gpa))

def main():

student1 = Student()

student1.firstName = “Albert”

student1.middleName = “Bob”

student1.lastName = “Cooper”

student1.studentId = 12359

student1.year = “Freshman”

student1.gpa = 3.1

student1.printInfo()

student2 = Student()

student2.printInfo()

if __name__ == ‘__main__’:

try:

main()

except KeyboardInterrupt:

print(“\nQuitting. Goodbye.”)

sys.exit()

Of course, the above code is inefficient, but I only wanted to demonstrate the basics of a class. You can have a class with attributes and methods. In this case, the above class has no constructor that accepts arguments, so you can only modify the instance variables using assignment and accessing the properties of an object. The better solution is to use constructors so that all of that stuff can be changed when the object is instantiated.

The above class has default values, which are not really necessary if you use a constructor properly. However, for some optional attributes, such as middle name, you might want to give the argument a default value in the constructor, as shown below.

Python constructors:

#!/usr/bin/env python3

import sys

class Student:

def __init__(self, first, last, sid, year, major, gpa, middle=””):

self.firstName = first

self.middleName = middle

self.lastName = last

self.studentId = sid

self.year = year

self.major = major

self.gpa = gpa

def printInfo(self):

print(“Name: ” + self.firstName + ” “, end=””)

if self.middleName != “”:

print(self.middleName + ” “, end=””)

print(self.lastName)

print(“Student ID: ” + str(self.studentId))

print(“Year: ” + self.year)

print(“Major: ” + self.major)

print(“GPA: ” + str(self.gpa))

def main():

student1 = Student(“Michael”, “Anderson”, 123460,

“Sophomore”, “Mathematics”, 3.4)

student1.printInfo()

if __name__ == ‘__main__’:

try:

main()

except KeyboardInterrupt:

print(“\nQuitting. Goodbye.”)

sys.exit()

Python inheritance:

class GradStudent(Student):

def __init__(self, first, last, sid, year, major, gpa,

thesis, isFullTime, greScores, gradMajor,

middle=””, specialization=””):

Student.__init__(self, first, last, sid, year, major, gpa, middle)

self.thesis = thesis

self.isFullTime = isFullTime

self.greScores = greScores

self.gradMajor = gradMajor

self.specialization = specialization

def main():

student1 = Student(“Michael”, “Anderson”, 123460,

“Sophomore”, “Mathematics”, 3.4)

student1.printInfo()

student2 = GradStudent(“Melissa”, “Adams”, 123789,

“5th”, “Computer Science”,

3.5, “using neural networks for infosec”,

False, [165, 163, 4.5], “Computer Science”,

“Chelsea”, “Cybersecurity”)

student2.printInfo()

The above example allows the GradStudent subclass to use the constructor and printInfo() method of the Student class. However, even with all the new attributes, the printInfo() method only prints out the properties that are in the Student superclass, meaning many useful pieces of information are missing.

The solution here is to override the printInfo() method.

Python polymorphism/overriding:

In Python, you simply redefine a method in order to override it. Unlike Java, there is no need for something like @Override before it.

Notice how the GradStudent subclass uses polymorphism for the printInfo() method. It looks very simple, but it allows for things like having an array of Student objects, some elements of which are GradStudents, and you can still do something like studentArray[x].printInfo() no matter what kind of student they are, but they will all have their own subclass implementations of the method.

#!/usr/bin/env python3

import sys

class Student:

def __init__(self, first, last, sid, year, major, gpa, middle=””):

self.firstName = first

self.middleName = middle

self.lastName = last

self.studentId = sid

self.year = year

self.major = major

self.gpa = gpa

def printInfo(self):

print(“Name: ” + self.firstName + ” “, end=””)

if self.middleName != “”:

print(self.middleName + ” “, end=””)

print(self.lastName)

print(“Student ID: ” + str(self.studentId))

print(“Year: ” + self.year)

print(“Major: ” + self.major)

print(“GPA: ” + str(self.gpa))

class GradStudent(Student):

def __init__(self, first, last, sid, year, major, gpa,

thesis, isFullTime, greScores, gradMajor,

middle=””, specialization=””):

Student.__init__(self, first, last, sid, year, major, gpa, middle)

self.thesis = thesis

self.isFullTime = isFullTime

self.greScores = greScores

self.gradMajor = gradMajor

self.specialization = specialization

def printInfo(self):

print(“Name: ” + self.firstName + ” “, end=””)

if self.middleName != “”:

print(self.middleName + ” “, end=””)

print(self.lastName)

if self.isFullTime:

print(“Full time “, end=””)

else:

print(“Part time “, end=””)

print(“graduate student”)

print(“Student ID: ” + str(self.studentId))

print(“Year: ” + self.year)

print(“Undergrad major: ” + self.major)

print(“Grad school major: ” + self.gradMajor)

print(“Specialization: ” + self.specialization)

print(“GPA: ” + str(self.gpa))

print(“Thesis: ” + self.thesis)

print(“GRE scores: “)

print(“Verbal reasoning: ” + str(self.greScores[0]))

print(“Quantitative reasoning: ” + str(self.greScores[1]))

print(“Analytical writing: ” + str(self.greScores[2]))

def main():

studentList = []

studentList.append(Student(“Michael”, “Anderson”, 123460,

“Sophomore”, “Mathematics”, 3.4))

studentList.append(GradStudent(“Melissa”, “Adams”, 123789,

“5th”, “Computer Science”,

3.5, “using neural networks for infosec”,

False, [165, 163, 4.5], “Computer Science”,

“Chelsea”, “Cybersecurity”))

for student in studentList:

student.printInfo()

# in the above line, there are two classes

# (Student and GradStudent)

# with different printInfo() methods,

# but they can both be called the same way

# this is what polymorphism is all about

if __name__ == ‘__main__’:

try:

main()

except KeyboardInterrupt:

print(“\nQuitting. Goodbye.”)

sys.exit()

Abstract classes in Python:

from abc import *

class Student(ABC):

def __init__(self, first, last, sid, year, major, gpa, middle=””):

self.firstName = first

self.middleName = middle

self.lastName = last

self.studentId = sid

self.year = year

self.major = major

self.gpa = gpa

@abstractmethod

def printInfo(self):

print(“Name: ” + self.firstName + ” “, end=””)

if self.middleName != “”:

print(self.middleName + ” “, end=””)

print(self.lastName)

print(“Student ID: ” + str(self.studentId))

print(“Year: ” + self.year)

print(“Major: ” + self.major)

print(“GPA: ” + str(self.gpa))

In the above example, the Student class is now an abstract class (because it extends ABC, which stands for Abstract Base Class). This means only subclasses of the abstract base class, such as GradStudent, can be instantiated. All abstract methods (designated with @abstractmethod) must be implemented. In this case, the only one the subclass needs to implement is printInfo(). Abstract classes are not suitable for all situations.

Creating objects in Python (there is no β€œnew” keyword):

someObject = someClass(arg1, arg2, arg3)

← Previous | Next β†’

Python Topic List

Main Topic List

Leave a Reply

Your email address will not be published. Required fields are marked *