Modifypy Un5
Modifypy Un5
of objects, which can contain data in the form of attributes and code in the form of methods.
Another definition of OOP is a way to build flexible and reusable code to develop more
advanced modules and libraries such as Numpy and Pandas.
Everything in Python is an object. For instance, string and list are Python objects. A class is like
a blueprint for creating objects. It is easy to maintain code that is written using OOP techniques
because of the modular structure. Programs are more secure with the encapsulation approach
used in OOP.
This tutorial discusses the fundamentals of object-oriented programming such as classes, objects,
methods, polymorphism, and inheritance to give you a good foundation in OOP.
Class
The present data structures in Python like integers and strings are designed to represent
something like the number of employees and the name of an employee. A class in OOP is like a
blueprint for objects, and you can develop your own data structure by using OOP. For example,
you could create an Employee class to track properties about the employee, such as the name or
salary.
The class keyword is used to create a class in Python. The class name follows the class keyword
followed by the colon. The body of the class starts on a new line and is indented one tab from the
class keyword.
Constructor is a method that is called by default whenever you create an object from a class. You
must create a method with keyword init to create a constructor. In the following example, I
create a class named Employee with two class attributes status and number_of_employee as well
as two instance attributes employee_id and name. The Employee class also contains
the give_info() method.
class Employee:
#class attributes
status = "active"
number_of_employee = 0
def __init__(self, employee_id, name):
self.employee_id = employee_id #instance attribute
self.name = name #instance attribute
Employee.number_of_employee += 1
#instance method
def give_info(self):
print("Name:",self.name,"\nID:",self.employee_id)
or variable, and the second employee_id is a parameter. The same thing is also true for
the name variable. When creating an object using a class, you can write emre = Employee("101",
"Emre Kutluğ"), 101 and Emre Kutluğ are arguments.
Object
As I said earlier, a class is like a blueprint for creating objects. The relationship between a class
and an object can be understood by looking at the relationship between an animal and Yogi Bear.
Yogi Bear is an animal. An animal is an abstract concept. It is implemented in the form of Yogi
Bear or Mickey Mouse. Therefore, we need to create an object of a class before we can use its
methods and attributes.
An object is also called an instance. Therefore, the process of creating an object of a class is
called instantiation. In Python, to create an object of a class, you must write the class name
followed by opening and closing parenthesis. In the following example, I create an object
of Employee class.
emre = Employee("101", "Emre Kutluğ")
I can use the type method to check the type of the object. As you see in the following example,
Input:
type(emre)
Output:
__main__.Employee
You can access class and instance attributes and call a instance method by using the class's
object. To do so, you must write the object name, followed by the dot (.) operator and the name
of the attribute or the method that you want to access or call. Look at the following examples.
Input:
emre.status
Output:
'active'
Input:
emre.number_of_employee
Output:
Input:
emre.employee_id
Output:
'101'
Input:
emre.give_info()
Output:
Attributes
You can use the built-in dir() function to see all of the attributes and methods of an object. There
are some built-in attributes and methods in Python. The following example shows all of the
attributes and methods of the emre object. The examples with double underscores in front are
built-in attributes and methods.
Input:
dir(emre)
Output:
['__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'employee_id',
'give_info',
'name',
'number_of_employee',
'status']
There are two types of attributes that are class and instance attributes. The value of class
attributes is the same across all objects, but the value of instance attributes can change across
objects. Instance attributes are declared inside any method while class attributes are declared
outside of methods. The instance attributes are referred by using the self keyword, while class
attributes are referred by the class name inside the method. In the
previous Employee class, status and number_of_employee are class
attributes, name and employee_id are instance attributes. In the following example, we look first
at the value of the number_of_employee attribute, and then we create another object from
the Employee class.
Input:
emre.number_of_employee
Output:
Input:
Input:
emma.give_info()
Output:
When we look at the value of number_of_employee in the following example, we see 2 in the
output because the number_of_employee attribute is a class attribute. Therefore, it's shared
between the objects.
Input:
emma.number_of_employee
Output:
2
Methods
As mentioned previously, you can implement the functions of an object using methods. I used
the objects of a class to call the methods so far, but there is another type of method that is a static
method that can be called directly using the class name. Static methods can only access class
attributes. In the following example, I add a static method to the Employee class.
Input:
class Employee:
#class attributes
status = "active"
number_of_employee = 0
#instance method
def give_info(self):
print("Name:",self.name,"\nID:",self.employee_id)
@staticmethod
def get_class_objective():
message = "The objective of this Employee class is to organize employee information
with more modular manner"
print (message)
Input:
Employee.get_class_objective()
Output:
The attributes of a class are also referred to as variables. There are two types of variables: local
and global. Local variables in a class are variables that can only be accessed inside the method
where it is defined. Therefore, you cannot access a message variable outside of
the get_class_objective() method. When you try to access it, it gives the AttributeError, as seen
in the following example.
Input:
emre.message
Output:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-15-35255f09e347> in <module>
----> 1 emre.message
Global variables are defined outside of any method, and they can be accessed anywhere in the
class. Status and number_of_employee are global variables in the previous example, so we can
access them as shown in the following example.
Input:
emre.status
Output:
'active'
Encapsulation
There are three main concepts in object-oriented programming: Encapsulation, Inheritance, and
Polymorphism. Encapsulation refers to data hiding. In OOP, one class should not have direct
access to the data of the other class, or the access should be controlled through instance methods.
You can use private variables and properties to control access to class data. To define a private
variable, you can put two underscores in front of the variable name. For instance, __age is a
private variable.
You can create a property for the age attribute that implements this logic, as shown in the
following code. A property has three parts. You must define the attribute, which is age in the
following example. Next, you must define the property for the attribute using
the @property decorator. Finally, you must create a property setter, which is
the @age.setter descriptor in the following example. You can say that the age of employees
should always between 18 - 99. If a user tries to enter a value for the age attribute that is less than
18 or greater than 99, there's an error and an object from the Employee class cannot be created.
However, if the value is between 18 - 99, an object can be created.
Input:
class Employee:
#class attributes
status = "active"
number_of_employee = 0
#instance method
def give_info(self):
print("Name:",self.name,"\nID:",self.employee_id)
@staticmethod
def get_class_objective():
message = "The objective of this Employee class is to organize employee information
with more modular manner"
print (message)
Input:
Output:
Inheritance
Inheritance in OOP is similar to real-world inheritance where a child inherits some of the
characteristics from his parents, in addition to his own unique characteristics. The class that
inherits another class is called a child class, and the class that is inherited by another class is
called a parent class. The following code shows an example of inheritance.
Input:
In the previous example, I create a Manager class that inherits the Employee class. To inherit a
class, you must write the parent class name inside the parenthesis that follows the child class
name. The Manager class can access all of the attributes and methods of the
parent Employee class, like shown in the following example.
Input:
Input:
muge.name
Output:
'Müge Özkan'
Input:
muge.status
Output:
'active'
Input:
muge.get_class_objective()
Output:
'The objective of this Employee class is to organize employee information with more
modular manner'
Show less
The Manager class also has its own method set_team_size() in addition to the Employee class'
methods and attributes. You can set the team size of the object of the Manager class as in the
following example. As a side note, one class can have more than two parent or child classes.
Input:
muge.set_team_size(10)
Input:
muge.team_size
Show less
Output:
10
Show less
Polymorphism
Polymorphism refers to the ability of an object to act in different ways. There are two types of
polymorphism: method overriding and method overloading.
Method overriding
Method overriding means having a method with the same name in the child class as in the parent
class. The definitions of such methods are different in parent and child classes, but the name
remains the same. If you remember, we had a give_info() method in the Employee class. We can
override this method in the child Manager class to give team size information about manager
objects.
Input:
class Manager(Employee):
team_size = 10
def give_info(self):
print("Name:",self.name,"\nID:",self.employee_id,"\nTeam Size:",self.team_size)
Input:
Input:
muge.give_info()
Output:
Input:
emre.give_info()
Output:
Method overloading
You can overload any method by changing the number or types of the arguments when you are
calling such methods and the methods behave differently. In the following example, if we call
the calculate_salary() method with one argument, it returns that argument. However, if we call
that method with two arguments, it returns a summation of the two arguments.
Input:
class Manager(Employee):
team_size = 10
def give_info(self):
print("Name:",self.name,"\nID:",self.employee_id,"\nTeam Size:",self.team_size)
Input:
Input:
muge.calculate_salary(12345)
Show less
Output:
12345
Input:
muge.calculate_salary(12345, 678)
Show less
Output:
13023
Conclusion