What are classes in python?

What are classes in python?

Python is an object-oriented programming language. In Python, everything is an object. All this time that you have been writing code, you have used objects. Either when you used built-in functions or the variables you created. An object is any data you can assign to a variable or pass as an argument to a function or method. A method is a function passed into an object.

Check my previous article if you are yet to learn about functions in Python.

In this article, you will learn about creating a class, inheritance and importing classes.

Classes in python text with the author's medium username

Creating a Class

A class is an outline or layout for creating objects. You can create many objects from a class. The object you create from a class is called an instance. You could also create methods. A class is like a recipe, while the food prepared is the object. A class is a layout for creating objects, so it does not hold any actual data. You cannot pass an argument to a class, but you can to an object.

To create a class, you begin with the word class then the class name, and a colon.

This is the syntax:

class ClassName:
    ''''Creating a simple syntax'''

Note: In Python, classes are capitalized in camel case. Eg: CamelCaseLetter

For example, if you wanted to create a class that records information about your students, you could do so.

class Student:
    '''Creating a class that records student details '''
    name = ""
    courses_complete  = 0
    certificates = 0

After creating the class, create an object, which is called an instance of the class. (I will be addressing it as an instance from now on to avoid any confusion.)

This is the syntax:

instance_name = ClassName()

#you do not need to capitalize the instance name or use Camel case.

You create the instance and assign it to the class name.

In the student record example, create the instance:

class Student:
    '''Creating a class that records student details '''
    name = ""
    courses_complete = 0
    certificates = 0


student_details = Student()

You can change the values for the class attributes when you want to access them.

student_details.name = "Ezinne Anne Emilia"

Now, print all the values for the attributes after modifying them.

class Student:
    '''Creating a class that records student details '''
    name = ""
    courses_complete = 0
    certificates = 0


student_details = Student()

student_details.name = "Ezinne Anne Emilia"     
#modifying the value of the name attribute 

student_details.courses_complete = 2       
#modifying the value of the courses_complete attribute 

student_details.certificates = 2       
#modifying the value of the certificates attribute 

print(f"Student's Name: {student_details.name} \n Courses Completed: {student_details.courses_complete} \n Certificates Received: {student_details.certificates}")       
#printing the values to the console

Output

Student's Name: Ezinne Anne Emilia
 Courses Completed: 2
 Certificates Received: 2

In the past example, you created attributes called name, courses_complete and certificates.

But to access these attributes, you had to change the values directly in the instance.

But wouldn’t it be better if you used those attributes as parameters? and passed the values as arguments in the instance instead? Of course, it would be. You can do that with a special method called the init method.

The init method

The init method is a constructor function. This function initializes a new instance of the class. Python requires the self parameter when initializing a new instance. So when you create an instance, Python will automatically pass the self parameter. You should surround the init method with double underscores. So the Python interpreter does not misinterpret it as a different method.

This is the syntax:

def __init__(self, attribute1, attribute2):
    self.attribute1 = attribute1
    self.attribute2 = attribute2

Now, use the init method in the Student class example

class Student:
    '''Creating a class that records student details'''

    def __init__(self,name,courses_complete,certificates):
        '''Initializing the attributes for the class instance'''
        self.name = name
        self.courses_complete = courses_complete
        self.certificates = certificates


student_details = Student('Ezinne Anne Emilia',2,2)  
# there's no  argument for the self parameter


print(f"Student's Name: {student_details.name} \n Courses Completed: {student_details.courses_complete} \n Certificates Received: {student_details.certificates}")

Output

Student's Name: Ezinne Anne Emilia
 Courses Completed: 2
 Certificates Received: 2

This makes the code cleaner, right?

Now, if you noticed when I filled in the arguments for the class, Student. I didn’t add an argument for the self parameter. This is due to the Python interpreter passing the self parameter to the student_details instance.

Now, you can add more methods to the code.

In the code example, you can add features that indicate when a student has started a course. And when a student has finished a course,

class Student:
    '''Creating a class that records student details '''

    def __init__(self,name,courses_complete,certificates):
        '''Initializing the attributes for the class instance'''
        self.name = name
        self.courses_complete = courses_complete
        self.certificates = certificates



    def start(self):
        '''Creating a method that indicates when a student starts a course'''
        print(f'This student: {self.name} has started a course')



    def complete(self):
        '''Creating a method that indicates when a student completes a course'''
        print(f'This student: {self.name} has completed a course')



student_details = Student('Ezinne Anne Emilia',2,2)


print(f"Student's Name: {student_details.name} \n Courses Completed: {student_details.courses_complete} \n Certificates Received: {student_details.certificates}")

When creating the methods (start and complete), you added the self parameter to them. This makes the attributes initialized in the constructor function available in the methods, too.

But you can add more parameters to the method after you add the self parameter.

...

    def start(self,prev_record):
        '''Creating a method that indicates when a student starts a course'''
        prev_record = 0
        print(f'This student: {self.name} has started a course \n Previous record = {prev_record}')
...

Calling the class instance

To call the methods that you created, you use the name of the instance and the name of the method.

This is the syntax:

instance_name.method_name()

To call the methods in the Student class.

class Student:
    '''Creating a class that records student details '''

    def __init__(self,name,courses_complete,certificates):
        self.name = name
        self.courses_complete = courses_complete
        self.certificates = certificates



    def start(self,prev_record):
        '''Creating a method that indicates when a student starts a course'''
        prev_record = 0
        print(f'This student: {self.name} has started a course \n Previous record = {prev_record}')



    def complete(self):
        '''Creating a method that indicates when a student completes a course'''
        print(f'This student: {self.name} has completed a course')



student_details = Student('Ezinne Anne Emilia',2,2)


print(f"Student's Name: {student_details.name} \n Courses Completed: {student_details.courses_complete} \n Certificates Received: {student_details.certificates}")

student_details.start(0)

student_details.complete()

Output

Student's Name: Ezinne Anne Emilia
 Courses Completed: 2
 Certificates Received: 2
This student: Ezinne Anne Emilia has started a course
 Previous record = 0
This student: Ezinne Anne Emilia has completed a course

Setting A Default Value

You could set a default value for an attribute without adding it as a parameter.

For example, if you wanted to record courses completed

You could create a default value in the constructor function.

class Student:
    '''Creating a class that records student details '''

    def __init__(self,name,courses_complete,certificates):
        self.name = name
        self.courses_complete = courses_complete
        self.certificates = certificates
        self.previous_record = 0


    ...

    def previous_courses(self):
        '''creating a method that records previous courses done'''
        print(f'Previous record: {self.previous_record}')


    ...


student_details.previous_courses()

You can modify previous_record directly like this:

student_details.previous_record = 1
student_details.previous_courses()

Instead of modifying it directly, you could also change the attribute through a method instead.

class Student:
    '''Creating a class that records student details '''

    def __init__(self,name,courses_complete,certificates):
        self.name = name
        self.courses_complete = courses_complete
        self.certificates = certificates
        self.previous_record = 0

    ...

    def update_previous_courses(self,updated_record):
        '''Creating a method to update previous courses done'''
        if updated_record != self.previous_record:
            self.previous_record = updated_record
        else:
            print('recorded')            
    ...


student_details.update_previous_courses(2)

student_details.previous_courses()

Inheritance

This is when the child class inherits the properties of the parent class. If you created a class called User and you wanted to create another class called UserProfile, you could inherit the properties of the parent class instead of writing the code from scratch.

This is the syntax:

class Parent:
    '''Creating a parent class'''


class Child(Parent):
    '''Creating a child class'''

    def __init__(self,param1,param2):
        '''Initializing'''
        super().__init__(parent_param1,parent_param2)

Inheriting from the parent

In the child class, you use the super method to initialize the attributes of the parent class.

In this example, the UserProfile class will inherit the attributes of the User class.

class User:
    '''creating a class for a user login attempts'''

    def __init__(self,device,ip_address):
        '''fixing the attributes for the user'''
        self.device = device   
        #attribute for the user's device
        self.ip_address = ip_address    
        #attribute for the user's ip address
        self.login_attempts = 0    
        #attribute for the user's login attempts


    def register(self):
        '''creating a method that describes the user's registration'''
        print(f'This user has been registered successfully')


    def location(self):
        '''creating a method that describes the user's location'''
        print(f'This {device} is located at the Northern hemisphere')


    def failed_logins(self):
        '''creating a method that records login attempts'''
        print(f'This user has {self.login_attempts} login attempts')


class UserProfile(User):
    '''Creating a child class UserProfile that will inherit some of the attributes of the parent class User'''


    def __init__(self,device,ip_address):
        '''Initializing the attributes of the parent class'''
        super().__init__(device,ip_address) 


user_profile = User('HuaweiX605','192.21.0.0')     
#assigning the arguments
print(f'This user is using a mobile device: {user_profile.device}\n Address: {user_profile.ip_address}')
user_profile.failed_logins()

You could add new attributes and methods to a child's class. In this example, you could add the name, age and username of the user and a method to describe the user profile.

class User:
    '''creating a class for a user login attempts'''

    def __init__(self,device,ip_address):
        '''fixing the attributes for the user'''
        self.device = device   
        #attribute for the user's device
        self.ip_address = ip_address    
        #attribute for the user's ip address
        self.login_attempts = 0    
        #attribute for the user's login attempts


    def register(self):
        '''creating a method that describes the user's registration'''
        print(f'This user has been registered successfully')


    def location(self):
        '''creating a method that describes the user's location'''
        print(f'This {self.device} is located at the Northern hemisphere')


    def failed_logins(self):
        '''creating a method that records login attempts'''
        print(f'This user has {self.login_attempts} login attempts')



class UserProfile(User):
    '''Creating a child class UserProfile that will inherit some of the attributes of the parent class User'''

    def __init__(self,device,ip_address,name,age,username):   
        #adding new attributes to the child class
        '''initializing the attribute of the parent in the child class'''
        super().__init__(device,ip_address)
        self.name = name
        self.age = age
        self.username = username



    def describe_user(self):
        '''describing a user'''
        print(f'User details: \n Name: {self.name} \n Age: {self.age} \n Username: {self.username}')


user_profile = UserProfile('Gionee360','197.60.12.3','Ezinne',16,'ezin5y')      #assigning the arguments
user_profile.location()       
#calling the method of the parent class on the child class
user_profile.describe_user()

Output

This Gionee360 is located at the Northern hemisphere
User details:
 Name: Ezinne
 Age: 16
 Username: ezin5y

Importing classes

In python, you can import classes in your code.

You can import a single class.

Syntax:

from file_name import ClassName

Command:

from user import User

You can import multiple classes from a file into the current code you are writing.

Syntax:

from file_name import ClassName1, ClassName2

instance_name = ClassName('attribute1','attribute2')

Command:

from user import User, UserProfile

user1 = User('device','address')

You can also import the whole file by specifying the file name.

Syntax:

import file_name

Command:

import user

To import all classes from a file into your present code.

Syntax:

from file_name import *

Command:

from user import *

To import a file and give it another name or alias

Syntax:

from file_name import ClassName as CN

Command:

from user import UserProfile as UP

Conclusion

By the end of this article, you will have learned about OOP in Python, how to create a class, the init method and methods, creating an instance, and how to import classes. You could try to repeat the initial exercises using the user login class this time around.