What are classes in python?
Tags: beginners, webdev, python, tutorial
Published: 2022-12-15 19:20:05

Python is an object-oriented programming language. [In Python, everything is an object](https://linux.die.net/diveintopython/html/getting_to_know_python/everything_is_an_object.html#d0e4665). 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](https://linux.die.net/diveintopython/html/getting_to_know_python/everything_is_an_object.html#d0e4665). A method is a function passed into an object.

*Check my previous article if you are yet to [learn about functions in Python](https://dev.to/ezinne_anne/what-are-functions-in-python--2nho).*

In this article, you will learn 

1. [Creating a Class](#creating)
   - [The init method](#init)
   - [Calling the class instance](#class)
   - [Setting A Default Value](#setting)
2. [Inheritance](#inheritance)
   - [Inheriting from the parent](#inherit)
3. [Importing classes](#import)
4. [Conclusion](#conclusion)


![Classes in python text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9p3k25yvil4x06ed6qc4.png) 

## Creating a Class <a name="creating"></a>
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:


```python
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. 

```python
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:

```python 
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:

```python
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.

```python
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**       <a name="init"></a>

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:

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

```

Now, use the `init` method in the `Student` class example

```python
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,

```python
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.


```python
...
        
    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**      <a name="class"></a>

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

This is the syntax:

```python
instance_name.method_name()

```

To call the methods in the `Student` class.

```python
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**      <a name="setting"></a>

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.


```python
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:

```python
student_details.previous_record = 1
student_details.previous_courses()
```

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

```python
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      <a name="inheritance"></a>
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:


```python
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**       <a name="inherit"></a>

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.

```python
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.

```python
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       <a name="import"></a>
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:

```python
from file_name import ClassName1, ClassName2

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

```

Command:
```python
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        <a name="conclusion"></a>
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.