Intro to Python Classes and Objects

Python is an object oriented Programming language, which focuses on dividing a program into objects, whereas procedure oriented programming focuses on dividing a program into functions. Objects are simply a collection of attributes (variables) and methods (functions) that act on those data and a class is a blueprint for that object. In this article by Vipul J, he does a great job explaining how Python classes can be thought of as blueprints of a house, and objects can be thought of as a particular instance of that house (there can be multiple objects for one class, while they all may differ in number of bedrooms/bathrooms/etc., they will all have the same blueprint of the class).
In computer programming, classes are a great way to organize attributes (variables) and methods (functions) so that they are easy to reuse and extend later. In this post, we will walk through how to build a basic class in python. Specifically, we will discuss the example of implementing a class that represents company employees.
First, let’s define a class that represents employees of a company – we must first do this before we create objects.
class Employee:
pass
Like the analogy described earlier, the "Employee" class serves as a blueprint for creating Employees and an instance of the "Employee" class may refer to a specific employee. Let’s see how we can define two employee instances, employee1 and employee2:
class Employee:
pass
employee1=Employee()
employee2=Employee()
print("Employee 1 is", employee1)
print("Employee 2 is", employee2)

Employee1 and employee2 are their own unique instances of the Employee class, this is confirmed by the unique memory address given to each employee. From our previous code, next we can create attributes for employee1 and employee2, their name and income.
class Employee:
pass
employee1=Employee()
employee1.name='Matt'
employee1.income=50000
print(employee1.name)
print(employee1.income)
employee2=Employee()
employee2.name='Penelope'
employee2.income=90000
print(employee2.name)
print(employee2.income)
# Output
Matt
50000
Penelope
90000
Here we can see that we’ve successfully added two variables to our employee1 and employee2 object. However, this is not the proper way to add attributes to objects, usually what we want to do is put attributes inside our class so that all the objects created from the class have these attributes by default. Similarly, we also put all methods inside our class so that every object of the class can access them. Let’s first see how we can add methods inside a class, then we will look into the proper way to create attributes.
class Employee:
def earning(self):
if self.income >= 80000:
return 'High Earning'
elif (self.income<8000) & (self.income>50000):
return "Medium Earning"
else:
return "Low Earning"
Here, I’ve defined a method earning inside the Employee class, now any object created from this class will have access to the earning method. As you can see, I used self as an argument and self.income inside the method, this is because whenever we define methods within a class we must use self as the first argument and represents the instance of a class (any name can be used in place of self as it is just an identifier like variable, but for code readability it’s best to keep it self).
Let’s see what level of earning employee1 is at:
employee1=Employee()
employee1.name='Matt'
employee1.income=50000
level_earning=employee1.earning()
print(level_earning)
# Output
Low Earning
As expected, level_earning printed "Low Earning" because employee1 earns less than the Medium Earning and less than the High Earning levels. In the line "level_earning=employee1.earning()", we are calling the earning method using the employee1 object. I have called this object without passing any argument, however because the method definition has an argument self, self refers to the employee1 object and self.income refers to the income attribute of the employee1 object, so the object is passed as the first argument automatically. If we create another object, employee2 and call this method then self will refer to the employee2 object and self.income will refer to the income attribute of the employee2 object. Let’s try it out:
employee1=Employee()
employee1.name='Matt'
employee1.income=50000
level_earning=employee1.earning()
print(level_earning)
employee2=Employee()
employee2.name='Penelope'
employee2.income=90000
level_earning=employee2.earning()
print(level_earning)
# Output
Low Earning
High Earning
We first get "Low Earning" for employee1 as his income is less than 80000, as defined in our earning method, and "High Earning" for employee2 as her income is above 80000.
Now, let’s add attributes to objects the proper way without adding them manually as we did earlier. Python offers a much more elegant and compact way of defining attributes right while instantiating the object, using the init() method. The init() method is a special method that automatically gets called every-time objects are created. As we did previously, we created attributes name and income, let’s define an init() method within our Employee class:
class Employee:
def __init__(self, name, income):
self.name=name
self.income=income
def earning(self):
if self.income >= 80000:
return 'High Earning'
elif (self.income<8000) & (self.income>50000):
return "Medium Earning"
else:
return "Low Earning"
employee1=Employee('Matt',50000)
print(employee1.name)
print(employee1.income)
# Output
Matt
50000
When we create an object, employee1, the init() method is called automatically with the values "Matt" and 50000 passed to name and income automatically. When looking at the parameters used in the init() method, we have self as the first argument because it is the object calling itself, while the second (name) and third (income) parameters take the two arguments which we used during object creation. For the employee1 object, the name attribute will be "Matt" because of the statement self.name=name and income will be 5000 because of the statement self.income=income. Let’s try creating another object, employee2:
class Employee:
def __init__(self, name, income):
self.name=name
self.income=income
def earning(self):
if self.income >= 80000:
return 'High Earning'
elif (self.income<8000) & (self.income>50000):
return "Medium Earning"
else:
return "Low Earning"
employee1=Employee('Matt',50000)
print(employee1.name)
print(employee1.income)
employee2=Employee('Penelope',90000)
print(employee2.name)
print(employee2.income)
# Output
Matt
50000
Penelope
90000
Great, it worked! Now, let’s see what level of earning Matt and Penelope are by calling the earning method:
class Employee:
def __init__(self, name, income):
self.name=name
self.income=income
def earning(self):
if self.income >= 80000:
return 'High Earning'
elif (self.income<8000) & (self.income>50000):
return "Medium Earning"
else:
return "Low Earning"
employee1=Employee('Matt',50000)
level_earning=employee1.earning()
print(employee1.name, "=", level_earning)
employee2=Employee('Penelope',90000)
level_earning=employee2.earning()
print(employee2.name, "=", level_earning)
# Output
Matt = Low Earning
Penelope = High Earning
As you can see, calling the earning method on the employee1 and employee2 objects tells us what level of earning each employee is at.
To review, we have created a class with two methods, an init() method that initializes attributes of name and income and an earning method that returns the level of earning depending on a person’s income. We then created two objects, employee1 with the parameters "Matt" and 50000, when these objects were created the init() method is called and name and income of the employee1 object are now "Matt" and 50000. Then we checked what level of earning employee1 is at and printed the results. We followed the same procedure when creating the employee2 object.
Thank you for reading! All code is available on my Github! 🙂