Object-Oriented Programming (OOP) in Python
Python inherently an object-oriented programming language, which makes it easy to work with classes and objects in Python.
Object-oriented programming is an example of a programming paradigms, which are a way to distinguish between different programming languages. Languages can belong to multiple paradigms.
In this tutorial, you will learn about object-oriented programming (OOP) in Python. We'll discuss the broad characteristics of object-oriented programming as well as several examples of how you can implement this paradigm in practice.
Table of Contents
You can skip to a specific section of this Python tutorial using the table of contents below:
What is Object-Oriented Programming?
Object-oriented programming is a powerful way to bundle your program into classes, instances, and objects. It is widely used for creating powerful and reliable applications. OOP also promotes software maintainability, which leads to better quality of code that is extensible with new attributes and functions.
Learning object-oriented programming can be a challenge for novice developers due to its complexity. It is also computationally intensive and consumes more memory than other paradigms. However, learning OOP is necessary for developers building modern and complex applications.
The relation between classes and objects can be best understood by an example. Consider a class named vehicle
. It would be a generic template that has the attributes of tires
, color
, vehicle_type
, and company
. An object of the class vehicle
, could be a toyota
and would have specific values for the attributes, which in this case could be 4
, red
, sedan
, and toyota
.
As you can see, object-oriented programming allows programmers to model real-life situations and objects. This is why OOP is so successful in the programming world.
Python is a multi-paradigm language and supports OOP and other paradigms. It is up to the discretion of the developer to select the most appropriate paradigm. Developers can choose to work with only one paradigm or multiple paradigms depending on their requirements.
OOP in Python
Python is a very powerful programming language. It is heavily supported by a robust community, has an easy-to-understand syntax, is dynamically-typed, and has high-level data types.
Being of dynamic nature, developers can choose not to declare the types of variables and arguments when creating them. These properties of python enable faster development and make the code much more readable.
Python's primitive data types (like lists, dictionaries and tuples) allow you to store simple data conveniently.
However, what if there is a more complex problem?
Imagine keeping a record of people where each person has a name, gender, age and other properties. It becomes difficult to store this information in primitive data types alone.
This is why we use classes. In this case, you'd create a class called person
. It will contain the arbitrary information that is common for all people, like name
, gender
, and age
.
The class acts like a blueprint. It does not contain actual information. To use classes, you create objects using this blueprint. This creates an instance
of that class.
In the next section, we'll create a class, define its attributes and create its objects.
Creating a Class
Now that you know the relation between classes and objects, you can go ahead and create classes in Python. It’s fairly simple and similar to the syntax used to create Python functions.
As an example, here's how you would create a class called Vehicle
:
class Vehicle:
def __init__(self):
pass
To define a class, you start with the keyword class, followed with the name of the class. Conventionally, CamelCase approach is followed to name the classes, starting with a capital letter.
This code creates a basic class. The ___init__(self)
method has to be defined inside each class. It later helps when creating instances of that class.
The keyword pass
allows us to run this code without an error. pass
is a null statement and is typically used as a placeholder, indicating that the code will be written in the future.
We will be dealing with the vehicle
class for the remainder of this tutorial. We will create instances of this class to help you better understand OOP in Python.
Now let’s see how you can create attributes of the class that was just created.
Creating Attributes
A class is an abstraction which is later implemented by the objects of the class. Each object has a set of characteristics defined by the class. These characteristics are known as attributes.
Here’s how you create attributes within our Vehicle
class:
class Vehicle:
horn = "honk honk"
def __init__(self, tires, color, vehType, company):
self.tires = tires
self.color = color
self.type = vehType
self.company = company
Here, we’ve defined the class vehicle
, which has the attributes of horn
, tires
, color
, and vehType
.
horn
is a pre-initialized attribute that the user will not have to set while creating an object. These attributes are known as class attributes and hold the same value for all instances of the class. The developer can change the value of class attributes if required.
The rest of the attributes need to be initialized while creating an object. These are known as instance attributes.
The self
variable is a special instance of the class, through which you can access the attributes and methods of the class. It binds the attributes with the given arguments.
Now let’s create some Vehicle
objects. Said differently, we will now create some instances of the Vehicle
class.
Instantiating Objects
Instantiating is the technical term for creating an object for a class. These objects are the useful representation of the class. In other words, classes usually can't serve a practical purpose until you use them to create objects.
In the following code block, two Vehicle
objects are initialized and their details are printed out.
class Vehicle:
horn = "honk honk"
def __init__(self, tires, color, vehType, company):
self.tires = tires
self.color = color
self.type = vehType
self.company = company
chevy = Vehicle(4, "RED", "TRUCK", "CHEVY")
ford = Vehicle(4, "BLUE", "TRUCK", "FORD")
print("This is my "+ chevy.color + " " + chevy.company + " " + chevy.type + " it has " + str(chevy.tires) + " tires.")
print("This is my "+ ford.color + " " + ford.company + " " + ford.type + " it has " + str(ford.tires) + " tires.")
Notice the print statement. Here you access the different properties of the objects via the dot operator. This way, you can access the desired properties and print out a meaningful sentence.
Save this code as classTest.py and execute it. You should get the following results:
C:\Users\Python> python classTest.py
This is my RED CHEVY TRUCK it has 4 tires.
This is my BLUE FORD TRUCK it has 4 tires.
Let’s see what happens when an object of a class is created. In this example, a new instance of the Vehicle
class is created and is assigned to variable chevy
. The attribute values are passed in as arguments.
These values are then processed by the init
function, which gets called when you create a new object. We do not pass anything for the self
argument because python determines the object to be a Vehicle
automatically and proceeds with the function, assigning the values.
Class Methods
Methods or functions are defined inside of the class and are used to access the value of attributes and or perform operations on their values. Just like the init
function, all methods starts with the keyword def
followed by the name of the function. The first argument of a class method is always self
.
Here’s an example of a simple method created for the Vehicle
class that represents the horn of a vehicle.
class Vehicle:
horn = "honk honk"
def __init__(self, tires, color, vehType, company):
self.tires = tires
self.color = color
self.type = vehType
self.company = company
def honk(self):
print(horn)
chevy = Vehicle(4, "RED", "TRUCK", "CHEVY")
chevy.honk()
When this code is executed, you’ll get the following output:
C:\Users\Python> python classTest.py
honk honk
You could also create a method to change the color of the vehicle.
class Vehicle:
horn = "honk honk"
def __init__(self, tires, color, vehType, company):
self.tires = tires
self.color = color
self.type = vehType
self.company = company
def honk(self):
print("honk honk")
def paintShop(self, color):
self.color = color
chevy = Vehicle(4, "RED", "TRUCK", "CHEVY")
print("This is my "+ chevy.color + " " + chevy.company + " " + chevy.type + " it has " + str(chevy.tires) + " tires.")
chevy.paintShop("PURPLE")
print("My Chevy's new color is: " + chevy.color)
When this code is executed, you’ll get the following output:
C:\Users\Python> python classTest.
This is my RED CHEVY TRUCK it has 4 tires.
My Chevy's new color is: PURPLE
In the code, the color attribute of the chevy truck object is updated and printed. Methods reduce repetition in code, improving readability and making development faster.
Class Inheritance
Inheritance is a very important concept of the object-oriented programming paradigm. It is the process by which a child class can inherit attributes and methods of a parent class.
The child classes override or extend the functionality offered by the parent class. This means that the child class has all the attributes and methods of the parent class, but can also specify different behavior as well.
In Python, all base classes are generally inherited from an object class. In Python 3, when you define a class, it is implicitly inherited from the object
class.
This means that the following two declarations are equivalent:
class Vehicle(object):
pass
#Python 3 does this implicitly
class Vehicle:
pass
Now let’s try inheritance with the Vehicle
class that we built earlier in this tutorial.
Child Class: Bike
We can inherit another class from the Vehicle
class to specify a special vehicle. In the code ahead, a Bike
class is created, which is a child class of Vehicle
.
class Bike(Vehicle):
def __init__(self, color, company):
self.tires = 2
self.color = color
self.type = "motorcycle"
self.company = company
def honk(self):
print("peep peep")
honda = Bike("GREEN", "HONDA")
print("My bike honks like: " + honda.horn)
honda.honk()
Since all bikes have the vehicle type motorcycle
, it is hardcoded into the class. The same logic applies for the tires
attribute. We have also updated the horn function of the Bike
class.
The Bike
class is inherited from the Vehicle
class but the fields have been updated to meet the specific requirements of a motorcycle.
This code generates the following output:
C:\Users\Python> python classTest.py
My bike honks like: honk honk
peep peep
This is inheritance in action. since the horn
attribute is defined in the Vehicle
attribute as “honk honk” and is not overridden in the Bike
child class, it outputs “honk honk” in the first line.
However, as the honk
function is overridden, it shows the output of the Bike
child class instead of the Vehicle
parent class’ honk
function.
Final Thoughts
Learning object-oriented programming is a requirement for any serious developer. It is implemented in all major programming languages due to its benefits and ability to simplify seemingly complex problems.
OOP allows better structuring of code. Python takes it one step further by using its simple and easy-to-understand syntax. However, it should be noted that OOP is not a unique concept of Python. Instead, it is a programming paradigm, applicable to a variety of programming languages.
Learning OOP will not only improve your Python skills, but will also give you an edge in other languages like Java and C++.