Mohanad Kaleia

Idea for a cause

OOP in Python

During my Master as a Computer Engineer, I worked with Python for data analysis, machine learning and deep learning projects. Python becomes more and more popular especially for writing AI and machine learning algorithms. But that is not the only thing that makes it great programming language, Python is just as C++ and Java supports Object Oriented Programming OOP. Which makes it suitable not just for research purposes but also for large scale applications.

In this article I will discuss OOP concepts in Python. As well as, we will highlight the differences in OOP between C++ and Python as a comparison between the two.

Python is designed from the beginning to support Object Oriented Programming concepts, providing the ability to build  large scale applications. If you don’t know or you kind of don’t remember the concepts of OOP we will review them here briefly in this article. OOP concepts are divided into 5 aspects as follow:
  • Class: represents a prototype for an object. This prototype describe object’s attributes and behavior
  • Object: an instance of its defined class (prototype). An object can hold values for attributes and execute functions defined by its prototype. 
  • Abstraction: with abstraction a class can hide some of its details and expose only specific information to the outside 
  • Inheritance: one of most important aspects in OOP is inheritance for code reusability. 
  • Polymorphisim: means the ability to have same function with different behavior.
We will go through these concepts one by one with an example for each of them. 

Class

In python a class can be created using the keyword class, as follow: 
class ClassName:
   'Optional class documentation string'
   class_suite
The three lines above describe how we can create new class in Python, where we start with the keyword class” then the class name we want with a semicolon. Just right after the definition the class we can write a description about it as in line number 2.The documentation can be accessed using the pre-defined class attribute __doc__. The rest will be the class body that defines the class attributes and functions. We will create now an example where we will create a class that represents a prototype of vehicle.

class Vehicle:
        'Vehicle class'

        # Class variable
        count = 0

        # Constructor
        def __init__(self, make, color, tag):
                self.make = make
                self.color = color
                self.tag = tag
                Vehicle.count += 1

        # Class function
        def printTag(self):
                print self.tag

        def printCount(self):
                print "Total number of created Vehicles %d" % Vehicle.count
The variable count” in line 5 represents a class variable that is shared between all instances. Function __init__ represents the constructor function. This is a special method that is called first thing when create an object. It takes the parameter self as first parameter, (all functions should contains self as a first argument). Where, self points to the object calling the method. 
Both methods have self as their first argument. C++ and Java both have a hidden first argument in their class methods, which points to the object that the method was called for and can be accessed using the keyword this. Python methods also use a reference to the current object, but when you are defining a method you must explicitly specify the reference as the first argument. No need to include it when calling a method from an object.
Instance variables or attributes are defined inside of a method. 
Here is how we create an instance of the class we just created: 
v1 = Vehicle('Mazda', 'Golden', 123456)
v2 = Vehicle('Toyoya', 'White', 987654321)

v1.printTag()
v2.printCount()
# Read object's attribute
print v1.make

# Write object attribute
v1.color = 'Red'

# Print the documentation of Vehicle's Class
print Vehicle.__doc__
 The output of the previous code:  

123456
Total number of created Vehicles 2
Mazda
An example for creating Class in Python

Inheritance 

In Python inheritance is done by write the base class(s) between parentheses as follow: 

class SubClass(ParentClass1 [,ParentClass2,...]):
  'Optional class documentation string'
   class_suite
Where inheritance is very useful for code reusability. As an example, we will create another class that inherits the base class Vehicle we created previously. We will name this class Truck. 
User-uploaded image: image.png

class Truck(Vehicle):
        def __init__(self, make, color, tag, numWheels):
                self.numWheels = numWheels
                Vehicle.__init__(self, make, color, tag)

        def printNumberOfWheels(self):
                print self.numWheels
                
        def printTag(self):
                print "Truck Vehicle with tag %d" % self.tag
  

truck1 = Truck('Toyoya', 'Yellow', 123, 8)
truck1.printCount()
truck1.printNumberOfWheels()
Output:
 

Total number of created Vehicles 3
8
In the constructor of the new subclass Truck, we called the init method of the parent class to initialize it with thee needed parameters. Inheritance allows subclasses to call method from their parents as we can see that the truck1 object can call function from Vehicle class print Count()”.

Overloading

Overloading allows us to redefine a function with different types of parameters. We will create another class for passenger vehicles and we will overload the method printTag() as folllow:

class Car(Vehicle):
        def __init__(self, make, color, tag, numPassenger):
                self.numPassenger = numPassenger
                Vehicle.__init__(self, make, color, tag)

        def numPassenger(self):
                print self.numPassenger

        def printTag(self):
                print "Passenger vehicle with tag %d" % self.tag
We see in the Car” class we have the function printTag same function in Truck class, but with different implementation where they print different text. Here we test the code we just wrote: 

truck1 = Truck('Toyoya', 'Yellow', 123, 8)
truck1.printTag()

car = Car('Mazda', 'White', 1, 4)
car.printTag()
 Output: 

Truck Vehicle with tag 123
Passenger vehicle with tag 1
In addition, we can overload predefined functions (e.g., __init__, __del__). 

Data Hiding:

Data hiding is used to hide or make some of class attributes or functions to be private. This is extremely useful when making a library to be used from other users and you don’t want to expose the  details of this library. Python support data hiding (Abstraction) by adding double underscore prefix before the attribute or the functions desired to be secret.  A secret attribute cannot be accessed directly out of the class, you need to write a getter function in order to get a secret variable.
class SecretClass:
        __secret = 0
        
        def __init__(self):
                SecretClass.__secret += 1
        
        def getSecret(self):
                print SecretClass.__secret
                
s = SecretClass()
s.getSecret()
print s.__secret
The last line will cause an error of unknown attribute. This is becuase we defined secret” to be private.

Overriding:

Overriding means to rewrite the behavior of a function inherited from a base class in the subclass. The following is an example of overriding: 
class parentClass:
  def doSomething(self):
    print "I'm parent class doing something"
    
class subclass(parentClass):
  def doSomething(self):
    print "I'm subclass class doing different thing"
    
c = subclass()
c.doSometing()
The output:
I'm subclass class doing different thing
Resources: 
  1. https://www.tutorialspoint.com/python/python_classes_objects.htm
  2. https://www.tutorialspoint.com/cplusplus/cpp_object_oriented.htm
  3. http://www.ddegjust.ac.in/studymaterial/mca-3/ms-17.pdf
  4. https://www.flaticon.com (I got some of the icon from here)

 

By Mohanad Shab Kaleia

Post a comment

  • *