In recent years, Python has become increasingly popular due to its simplicity and versatility. One of the key features behind its popularity is its support for object-oriented programming (OOP) through the use of classes and objects.
Python classes and objects are essential components of the language and provide a robust way for organizing and structuring code. Therefore, understanding how to use classes and objects effectively can greatly improve the readability, reusability, and maintainability of your code.
In the previous blog of this series, we discussed Python Lists, Python Operators, Python Functions, Python Pandas, and the usage of Python Comments.
This blog will cover the basic and advanced concepts of Python classes and objects, including inheritance, encapsulation, and polymorphism. Moreover, you will also learn about the methods, properties, and approaches for modifying object properties.
So get ready to master one of the most essential OOP concepts in the Python programming language!
1. Understanding Python Classes
In Python, a class is considered a blueprint for creating or defining objects having similar behaviors and properties. It offers an effective approach to organizing and encapsulating data and functions together in a single unit which makes it easier to reuse or manage code.
Classes define a set of attributes and methods that are associated or linked with the objects from which they are created.
Each object comprises its own set of methods and attributes, which can be accessed or modified as per requirements.
1.1 Syntax for Creating a Class in Python
Follow the provided syntax for creating a class in Python.
class ClassName: # class variables and methods
Here, the “class
” keyword defines the new class followed by its name and a colon. The class body will contain the respective variables and methods.
1.2 How to Create a Python Class
For the demonstration, we have created a Python class named “Person
” having a class variable “species
“. This variable will be shared by all of the class instances.
Next, we have defined a “greet()
” method that prints a welcome message with the person’s name.
After that, an initializer method “__init__()
” is defined that is invoked when a new object is created from the class. In our case, this method initializes two attributes “name
” and “age
” of the object.
class Person: # class variable species = "human" # class method def greet(self): print("Hi GeekVeda User! my name is", self.name) # initializer method def __init__(self, name, age): self.name = name self.age = age
Now, you should be wondering how to use this Python class and its relevant methods. Well, for the corresponding purpose, class objects are created!
2. Definition and Purpose of Python Objects
A Python object is known as the instance of a class. This instance represents a unique entity having its own set of attributes known as data members and methods or functions.
You can create objects of a class by utilizing the “__init__()
” method. This method assists in initializing the object attributes.
The main purpose behind creating objects is to permit code modularity and reusability. After defining a class, you can create multiple objects from it having their own unique methods and attributes.
This operation makes it easy to manage and organize code, which ultimately increases its readability.
2.1 What are the Properties and Methods of Objects
Properties of a Python object represent its respective attributes that can be accessed and modified using the dot “.”
notation. Whereas, methods are the functions defined in a class that can be invoked or called on the object for performing different types of tasks.
2.2 Create an Object and Access its Properties and Methods
Let’s check out an example related to creating an object and accessing its properties and methods.
For this purpose, we have created a class named “Person
” having three attributes “name
“, “age
“, and “gender“, and a method “greet()
“.
Then, we created an object named “person1
” of the Person class and passed “Sharqa
“, 25, and “female
“, as the arguments to the “__init__()
” method. The specified values will be assigned to name, age, and gender parameters.
Now, to access the object properties, use the dot notation. For instance, to access the specified name, we have written “person1.name
“. The same procedure has been followed for accessing the age and gender of the same object.
Lastly, the “greet()
” method is invoked to display the welcome message.
class Person: def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender def greet(self): print("Hi GeeksVeda User, my name is", self.name) # creating a new Person object person1 = Person("Sharqa", 25, "female") # accessing object properties print(person1.name) print(person1.age) print(person1.gender) # calling object methods person1.greet()
2.3 Create and Modify Object Attributes in Python
Now, continuing the same example, we will create a new object named “person1
” and define a new attribute for it as “email
“.
The value of this attribute will be assigned using the dot notation. After doing so, we will access and modify the email value again by utilizing the dot notation.
class Person: def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender def greet(self): print("Hi GeeksVeda User, my name is", self.name) # creating a new Person object p1 = Person("Sharqa", 25, "female") # creating a new object attribute p1.email = "sharqa@geeksveda.com" # accessing and modifying object attributes print(p1.email) p1.email = "sharqahameed@geeksveda.com" print(p1.email)
It can be observed from the output that the initial email of the person1 was “sharqa@geeksveda.com” which has been accessed and modified to “sharqahameed@geeksveda.com“.
3. Class Inheritance in Python
In Python, class inheritance is a way used for creating a new class that is the modified or updated version of the existing or already defined class.
In this approach, the new class or subclass inherits all the methods and attributes of the existing or parent class. Moreover, you are also allowed to add your own methods and attributes to the subclass or modify the existing ones.
3.1 Purpose of Implementing Class Inheritance in Python
As discussed earlier, class inheritance is a logical concept that is implemented to create classes based on the existing ones and add some updated features as well. The purpose of applying inheritance is to avoid redundancy and reuse the code.
Inheritance also permits you to define a generic class, define more specific classes that can inherit from it, and add other functionalities.
3.2 Syntax of Class Inheritance in Python
In the given syntax, “ChildClass
” is the subclass that is inherited from the “ParentClass
“. Its definition includes the parent class name passed as an argument. This also indicates that ChildClass is a subclass.
class ParentClass: # parent class attributes and methods class ChildClass(ParentClass): # child class attributes and methods
3.3 Create a Subclass From a Part Class in Python
In order to create a subclass, it is essential to define the parent class first. Let’s say that, in the given code, “Person
” is our parent class, and “Employee
” is its child class.
This child class inherits the “__init__()
” method from the parent class to specify the name, age, and gender.
Additionally, the Employee class overrides the initializer method to add the “id_number
” and the “department
” attributes. Moreover, we have also defined a new “display_employee()
” method for showing the new attribute values.
class Person: def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender def greet(self): print("Hi GeeksVeda User, my name is", self.name) class Employee(Person): def __init__(self, name, age, gender, id_number, department): super().__init__(name, age, gender) self.id_number = id_number self.department = department def display_employee(self): print("ID:", self.id_number) print("Department:", self.department) employee1 = Employee("Sharqa", 25, "female", 98765, "CS") print(employee1.name) print(employee1.age) employee1.display_employee()
3.4 Override Method in a Subclass in Python
In the previous section, you have seen that the “__init__()
” method was defined in the subclass, which was also present in the parent class. This is known as method overriding. It is a common pattern that can be followed while implementing class inheritance.
The subclass is permitted to override the parent class methods for customizing their behaviors. Both parent and subclass can have methods with similar names and different implementations.
For instance, in the provided code, “Author
” is a subclass of the “Person
” class. This subclass overrides both “__init__()
” to assign the “author_id
” value and the “greet()
” method to display the author_id along with the functionality added in both of the parent class methods respectively.
class Author(Person): def __init__(self, name, age, gender, author_id): super().__init__(name, age, gender) self.author_id = author_ids def greet(self): super().greet() print("Author ID:", self.author_id) author1 = Author("Sharqa", 25, "female", 98765) author1.greet()
Lastly, the object “author1
” of the subclass is created and the values of the name, age, gender, and autho_id attributes have been passed.
The child class initializer “__init__()
” calls the parent class initializer method using “super()
“, which then performs its functionality, and then the execution control shifts back to the subclass initializer method.
Similarly, when the “greet()
” method is called, it then invokes the parent class greet()
method for displaying the welcome message with the name of the person. Then, the subclass corresponding method prints out the author_id value.
4. Encapsulation in Python Classes
Encapsulation is a phenomenon that is utilized for binding data and methods together within a class and prevents it from being accessed outside the class, without permission.
This mechanism assists in protecting the internal data of the classes from being accidentally updated. Moreover, it also offers a way for implementing access control.
4.1 Purpose of Implementing Encapsulation in Python Classes
The primary purpose of implementing encapsulation is to protect the internal object stated from being modified by the external code and to offer a consistent and clean interface for using the class object.
4.2 What are Access Modifiers in Python Classes
In Python, access modifiers are utilized for defining the class members, like methods and attributes. There are three kinds of access modifiers in Python, Public, Private, and Protected.
- Public Member – These types of members are accessible from anywhere, like outside or within the class. More specifically, public members do not have any access modifiers and are only represented by their names.
- Private Members – These types of members are accessible only within the class and are denoted by the double underscore “
__
” which is added at the start of their names. - Protected Members – These types of members are denoted by a single underscore “
_
” added at the start of their name. You can access them within the parent and subclasses.
4.3 How to Use Access Modifiers in Python Classes
Here, the “Person
” class has two protected attributes “_name
“, and “_age
” and one private attribute named “__ssn
“.
This class also has a method “display_info()
” that prints the values of all of the mentioned three attributes.
class Person: def __init__(self, name, age): self._name = name self._age = age self.__ssn = "789-22-1234" def display_info(self): print("Name:", self._name) print("Age:", self._age) print("SSN:", self.__ssn) person1 = Person("Sharqa Hameed", 25) person1.display_info() print(person1._name) print(person1._age) print(person1.__ssn)
Now, an instance of the “Person
” class has been created named “person1
“. After that, we called the “display_info()
” method for displaying the attribute values.
Then, we also accessed the “_name
” and “_age
” attributes directly outside of the class. However, when we tried to access the “__ssn
” private attributes, we got the following “AttributeError
” indicating that _ssn
is a private attribute.
5. Polymorphism in Python Classes
Polymorphism is an object’s ability to take more than one or multiple forms. It is a fundamental OOP concept that enables the code to be written to work with objects of several classes in a uniform way.
5.1 Types of Polymorphism in Python Classes
There exist two types of polymorphism.
- Method Overriding – As discussed earlier, it is the procedure of redefining the parent class method in the child method to customize its behavior.
- Method Overloading – In this approach, multiple methods are defined with a similar name but with different parameters. When a method is invoked, one of its forms is called after checking the number of types of the passed argument. However, remember that Python does not support Method overloading.
5.2 Why Python Doesn’t Support Method Overloading
Check out the enlisted reason for getting the answer to the mentioned question.
- As you know, Python is a dynamically typed language, which signifies that the method calls are resolved at the run time and the object and variable type are determined at the run time. This makes it difficult to conclude which method should be called or invoked based on the type of arguments.
- The use of method overloading does not follow the core principles of Python which are simplicity and readability.
- Moreover, method overloading can lead to bugs and unnecessary codebases, especially in large codebases.
6. Advantages of Using Python Classes and Objects
Here are some of the most essential advantages of utilizing classes and objects in Python.
- Classes and objects permit you to organize the code into reusable and modular units which also make it easy to read, write, and maintain code.
- While writing Python code, you can implement inheritance so that the child class can inherit the methods and attributes of the child class. This can save a lot of effort and time.
- Classes and objects offer a way for hiding the code complexity.
- As classes and objects represent the real-world object and their system, making it easier for the developers to understand the nature of the work and the relevant code.
- Implementing polymorphism makes your code more adaptable and flexible.
That was all about Python Classes and objects.
Conclusion
Python classes and objects offer an adaptable approach to representing systems and objects of the real world. Python classes can facilitate the definition of more effective, reusable, and manageable code as they permit you to implement properties, methods, inheritance, encapsulation, and polymorphism.
By mastering the fundamentals of Python classes and objects, you can step up your programming skills.
Want to explore more? Check out our dedicated Python Tutorial series!