Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
220 views

Python Classes Objects Special Methods Inheritance, Polymorphism, Encapsulation

The document discusses a unit on object-oriented programming principles in Python, including inheritance, polymorphism, encapsulation, and abstraction. It provides examples of defining classes and objects, creating instance methods, using access specifiers, and exception handling. Constructors and inheritance are demonstrated through examples creating Bike and Employee classes. Encapsulation is achieved through private attributes denoted with double underscores.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
220 views

Python Classes Objects Special Methods Inheritance, Polymorphism, Encapsulation

The document discusses a unit on object-oriented programming principles in Python, including inheritance, polymorphism, encapsulation, and abstraction. It provides examples of defining classes and objects, creating instance methods, using access specifiers, and exception handling. Constructors and inheritance are demonstrated through examples creating Bike and Employee classes. Encapsulation is achieved through private attributes denoted with double underscores.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 138

Python Programming (CSE3011) |

LP (3 credits)
UNIT – 3
Python Inheritance, Polymorphism, Encapsulation
Abstraction
By
Dr. MK Jayanthi Kannan, B.E.,M.E.,MS.,MBA.,M.Phil., Ph.D.,
Professor School of Computing Science and Engineering,
AB 104, 8.30am- 5.pm
VIT Bhopal University, Bhopal-Indore Highway,
Kothrikalan, Madhya Pradesh - 466114.
email: jayanthi.m@vitbhopal.ac.in, Emp Id : 100600
Ph: +91 6379397594
UNIT – 3 Python Inheritance, Polymorphism, Encapsulation
Abstraction
The following topics we are going to discuss in UNIT 3
OOPs in Python Programming
• persistent storage of objects,
 Principles of Object Orientation, • inheritance,
 Classes in Python, • polymorphism,
 Creating Classes, • operator
 Instance Methods, • overloading,
 Access Specification, • abstract classes,
 data modeling,
• exception handling.
 try block
# define a class
class Bike:
name = "" gear = 0
# create object of class
bike1 = Bike() # access attributes
and assign new values
bike1.gear = 11
bike1.name = "Mountain Bike“
print(f"Name: {bike1.name},
Gears: {bike1.gear} ")
# define a class
class Employee:
# define an attribute
employee_id = 0

# create two objects of the Employee class


employee1 = Employee()
employee2 = Employee()

# access attributes using employee1


employee1.employeeID = 1001
print(f"Employee ID: {employee1.employeeID}")

# access attributes using employee2


employee2.employeeID = 1002
print(f"Employee ID: {employee2.employeeID}")
#Python Methods
#We can also define a function inside a Python class.
#A Python Function defined inside a class is called a method.
#Let's see an example,
# create a class
class Room:
length = 0.0
breadth = 0.0

# method to calculate area


def calculate_area(self):
print("Area of Room =", self.length * self.breadth)

# create object of Room class


study_room = Room()

# assign values to all the attributes


study_room.length = 42.5
study_room.breadth = 30.8

# access method inside class


study_room.calculate_area()
Python Constructors Here, _init_() is the constructor function that is
Earlier we assigned a default value to a called whenever a new object of that class is
class attribute, instantiated.

class Bike: The constructor above initializes the value of


name = "" the name attribute. We have used the
... self.name to refer to the name attribute of the
# create object bike1 object.
bike1 = Bike()
However, we can also initialize values using If we use a constructor to initialize values inside
the constructors. For example, a class, we need to pass the corresponding
value during the object creation of the class.
class Bike:
# constructor function bike1 = Bike("Mountain Bike")
def _init_(self, name = ""): Here, "Mountain Bike" is passed to the name
self.name = name parameter of _init_().
bike1 = Bike()
Index

1. Introduction to Object Oriented Programming in Python


2. Difference between object and procedural oriented
programming
3. What are Classes and Objects?
4. Object-Oriented Programming methodologies:
• Inheritance
• Polymorphism
• Encapsulation
• Abstraction

2
1
1. Introduction to Object Oriented
Programming in Python

Object Oriented Programming is a way of


computer programming using the idea of
“objects” to represents data and methods. It is
also, an approach used for creating neat and
reusable code instead of a redundant one.

2
2
2. Difference between Object-Oriented and
Procedural Oriented Programming

Procedural-Oriented Programming
Object-Oriented Programming (OOP)
(Pop)

It is a bottom-up approach It is a top-down approach


Program is divided into objects Program is divided into functions

Makes use of Access modifiers


Doesn’t use Access modifiers
‘public’, private’, protected’

It is more secure It is less secure

Object can move freely within member Data can move freely from function to
functions function within programs

It supports inheritance It does not support inheritance


3. What are Classes and Objects?

A class is a collection of objects or you can say it is a


blueprint of objects defining the common attributes and
behavior. Now the question arises, how do you do that?

Class is defined under a “Class” Keyword.

Example:

class class1(): // class 1 is the name of the class

2
4
# Python program to display the no of sides of polygonand find out
the area of the triangle

class Polygon:
def _init_(self, no_of_sides):
self.n = no_of_sides
self.sides = [0 for i in range(no_of_sides)]

def inputSides(self):
self.sides = [float(input("Enter side "+str(i+1)+" : ")) for i in range(self.n)]

def dispSides(self):
for i in range(self.n):
print("Side",i+1,"is",self.sides[i])
# Python program to display the no of sides of # Creating an instance of the Triangle class
polygonand find out the area of the triangle t = Triangle()

class Triangle(Polygon): # Prompting the user to enter the sides of the triangle
# Initializing the number of sides of the triangle to 3 t.inputSides()
by
# calling the _init_ method of the Polygon class # Displaying the sides of the triangle
def _init_(self): t.dispSides()
Polygon._init_(self,3)
# Calculating and printing the area of the triangle
def findArea(self): t.findArea()
a, b, c = self.sides
Output
# calculate the semi-perimeter Enter side 1 : 3
s = (a + b + c) / 2
Enter side 2 : 5
# Using Heron's formula to calculate the area of Enter side 3 : 4
the triangle Side 1 is 3.0
area = (s*(s-a)(s-b)(s-c)) ** 0.5
print('The area of the triangle is %0.2f' %area)
Side 2 is 5.0
Side 3 is 4.0
The area of the triangle is 6.00
Creating an Object and Class in python:

Example:

class employee():
def init (self,name,age,id,salary): //creating a function
self.name = name // self is an instance of a class
self.age = age
self.salary = salary
self.id = id

emp1 = employee("harshit",22,1000,1234) //creating objects


emp2 = employee("arjun",23,2000,2234)
print(emp1. dict )//Prints dictionary

2
7
class Circle(object):

Def__init__ (self, center, radius):


self.center = center self.radius = radius

Def__ draw__(self, canvas): rad = self.radius

x1 = self.center[0]-rad y1 = self.center[1]-rad
x2 = self.center[0]+rad y2 = self.center[1]+rad

canvas.create_oval(x1, y1, x2, y2, fill='green')

def move(self, x, y): self.center = [x, y]


# Python Encapsulation class Computer:
• Encapsulation is one of the key def _init_(self):
features of object-oriented self.__maxprice = 900
programming. def sell(self):
• Encapsulation refers to the bundling of print("Selling Price: {}".format(self.__maxprice))
attributes and methods inside a single
class. def setMaxPrice(self, price):
• It prevents outer classes from self.__maxprice = price
c = Computer()
accessing and changing attributes and c.sell()
methods of a class. # change the price
• This also helps to achieve data hiding. c.__maxprice = 1000
• In Python, we denote private c.sell()
attributes using underscore as the # using setter function
prefix i.e single _ or double __. For c.setMaxPrice(1000)
c.sell()
example,
Output

Selling Price: 900


Selling Price: 900
Selling Price: 1000

• In the above program, we defined a Computer class.


• We used _init_() method to store the maximum selling price of
Computer. Here, notice the code
• c.__maxprice = 1000
• Here, we have tried to modify the value of __maxprice outside of the
class. However, since __maxprice is a private variable, this modification is
not seen on the output.
• As shown, to change the value, we have to use a setter function i.e
setMaxPrice() which takes price as a parameter.
Python Encapsulation and Variable Hiding
using self with an instance Variable
class company():
def __init__ (self): #private function
self. __companyname=("Google") # Variable Hiding using self with an instance Variable
def companyname (self):
print (self.__companyname)

c1.company()
c1.companyname()
Object-Oriented Programming
methodologies:

 Inheritance
 Polymorphism
 Encapsulation
 Abstraction

3
2
Inheritance:

Ever heard of this dialogue from relatives “you look exactly


like your father/mother” the reason behind this is called
„inheritance‟. From the Programming aspect, It generally
means “inheriting or transfer of characteristics from parent to
child class without any modification”. The new class is called
the derived/child class and the one from which it is derived is
called a parent/base class.
9
Single
Inheritance
Multiple
Inheritance
Python Inheritance Syntax
Here's the syntax of the inheritance in Python,

Python Inheritance
Like any other OOP languages, Python also supports the
concept of class inheritance.

Inheritance allows us to create a new class from an


existing class.

The new class that is created is known as subclass (child


or derived class) and the existing class from which the
child class is derived is known as superclass (parent or
base class).
Python Inheritance Syntax

# define
` a superclass
class super_class:
# attributes and method definition

# inheritance
class sub_class(super_class):
# attributes and method of super_class
# attributes and method of sub_class

Here, we are inheriting the sub_class class from the


super_class class.
#Example Python Inheritance # create an object of the subclass
class Animal: labrador = Dog()
# attribute and method of the parent class
name = "" # access superclass attribute and
def eat(self): method
print("I can eat") labrador.name = "Rohu"
labrador.eat()
# inherit from Animal
class Dog(Animal):
# call subclass method
# new method in subclass
def display(self): labrador.display()
# access name attribute of superclass
using self
print("My name is ", self.name)
#Python Class and Object
class Parrot:
# class attribute # access attributes
name = "" print(f"{parrot1.name} is {parrot1.age} years
age = 0 old")
print(f"{parrot2.name} is {parrot2.age} years
# create parrot1 object old")
parrot1 = Parrot()
parrot1.name = "Blu"
parrot1.age = 10

# create another object parrot2


parrot2 = Parrot()
parrot2.name = "Woo"
parrot2.age = 15
# derived class
#Python Inheritance class Dog(Animal):
• Inheritance is a way of creating a new
class for using details of an existing class def bark(self):
without modifying it. print("I can bark! Woof woof!!")
# Create object of the Dog class
• The newly formed class is a derived class dog1 = Dog()
(or child class). Similarly, the existing
class is a base class (or parent class). # Calling members of the base class
#Example Use of Inheritance in Python dog1.eat()
# base class dog1.sleep()
class Animal: # Calling member of the derived class
dog1.bark();
def eat(self): Here, dog1 (the object of derived class Dog)
print( "I can eat!") can access members of the base class Animal.
It's because Dog is inherited from Animal. #
def sleep(self): Calling members of the Animal
print("I can sleep!") classdog1.eat()dog1.sleep()
Single Inheritance:

Single level inheritance enables a derived class to inherit


characteristics from a single parent class.
Example:

class employee1()://This is a parent class


def init (self, name, age, salary):
self.name = name
self.age = age
self.salary = salary

class childemployee(employee1)://This is a child class


def init (self, name, age, salary,id):
self.name = name
self.age = age
self.salary = salary
self.id = id
emp1 = employee1('harshit',22,1000)
print(emp1.age)

Output: 22
Multilevel Inheritance:

Multi-level inheritance enables a derived class to inherit properties from an


immediate parent class which in turn inherits properties from his parent
class.

Example:

class employee()://Super class


def init (self,name,age,salary):
self.name = name
self.age = age
self.salary = salary
class childemployee1(employee)://First child class
def init (self,name,age,salary):
self.name = name
self.age = age
self.salary = salary
class childemployee2(childemployee1)://Second child class
def init (self, name, age, salary):
self.name = name
self.age = age
self.salary = salary
emp1 = employee('harshit',22,1000)
emp2 = childemployee1('arjun',23,2000)

print(emp1.age)
print(emp2.age)

Output: 22,23
Hierarchical Inheritance:

Hierarchical level inheritance enables more than one derived


class to inherit properties from a parent class.

Example:

class employee():
def init (self, name, age, salary): //Hierarchical Inheritance
self.name = name
self.age = age
self.salary = salary
class childemployee1(employee):
def init (self,name,age,salary):
self.name = name
self.age = age
self.salary = salary

class childemployee2(employee):
def init (self, name, age, salary):
self.name = name
self.age = age
self.salary = salary
emp1 = employee('harshit',22,1000)
emp2 = employee('arjun',23,2000)
Multiple Inheritance:

Multiple level inheritance enables one derived class to inherit


properties from more than one base class.

Example:

class employee1(): //Parent class


def init (self, name, age, salary):
self.name = name
self.age = age
self.salary = salary
class employee2(): //Parent class
def init (self,name,age,salary,id):
self.name = name
self.age = age
self.salary = salary
self.id = id

class childemployee(employee1,employee2):
def init (self, name, age, salary,id):
self.name = name
self.age = age
self.salary = salary
self.id = id

emp1 = employee1('harshit',22,1000)
emp2 = employee2('arjun',23,2000,1234)
Python Multiple Inheritance Syntax
class SuperClass1:
# features of SuperClass1

class SuperClass2:
# features of SuperClass2

class MultiDerived(SuperClass1, SuperClass2):


# features of SuperClass1 + SuperClass2 + MultiDerived class Here, the MultiDerived
class is derived from SuperClass1 and SuperClass2 classes.
class father():
f_name="Raja"
f_age=45
f_accountinfo="1000"

class mother(): obj=son()


print("father Name, age , accountinfo is:", obj.f_name, obj.f_age, obj.f_accountinfo)
m_name="Rani" print("Mother Name, age , accountinfo is:", obj.m_name, obj.m_age, obj.m_accountinfo)
m_age=37 print("Son Name, age , accountinfo is:", obj.s_name, obj.s_age, obj.s_accountinfo)
m_accountinfo="1001"
fobj=father()
print("father Name, age , accountinfo is:", fobj.f_name, fobj.f_age, fobj.f_accountinfo)
class son(father, mother): print("Mother Name, age , accountinfo is:", fobj.m_name, fobj.m_age, fobj.m_accountinfo)
s_name="Prince" print("Son Name, age , accountinfo is:", fobj.s_name, fobj.s_age, fobj.s_accountinfo)
s_age=25 mobj=mother()
s_accountinfo="1008" print("father Name, age , accountinfo is:", mobj.f_name, mobj.f_age, mobj.f_accountinfo)
print("Mother Name, age , accountinfo is:", mobj.m_name, mobj.m_age,
mobj.m_accountinfo)
print("Son Name, age , accountinfo is:", mobj.s_name, mobj.s_age, mobj.s_accountinfo)
#Example: Python Multiple Inheritance
class Mammal:
def mammal_info(self):
Output
print("Mammals can give direct birth.") Winged animals can flap.
In the above example, the Bat class is derived from two
class WingedAnimal: super classes: Mammal and WingedAnimal. Notice the
def winged_animal_info(self): statements,
print("Winged animals can flap.")
class Bat(Mammal, WingedAnimal): b1 = Bat()
pass b1.mammal_info()
b1.winged_animal_info()
# create an object of Bat class
b1 = Bat() Here, we are using b1 (object of Bat) to access
mammal_info() and winged_animal_info() methods of
b1.mammal_info() the Mammal and the WingedAnimal class respectively.
b1.winged_animal_info()
Run Code
Python Multilevel Inheritance
In Python, not only can we derive a class from the superclass but you can also derive a
class from the derived class. This form of inheritance is known as multilevel
inheritance.
The syntax of the multilevel inheritance

class SuperClass:
# Super class code here

class DerivedClass1(SuperClass):
# Derived class 1 code here

class DerivedClass2(DerivedClass1):
# Derived class 2 code here
#Here, the DerivedClass1 class is derived from the SuperClass class, and the
DerivedClass2 class is derived from the DerivedClass1 class.
#Example: Python Multilevel Inheritance
class SuperClass:
# create an object of DerivedClass2
def super_method(self): d2 = DerivedClass2()
print("Super Class method called")
d2.super_method() # Output: "Super Class
# define class that derive from SuperClass method called"
class DerivedClass1(SuperClass):
def derived1_method(self): d2.derived1_method() # Output: "Derived
print("Derived class 1 method called") class 1 method called"

# define class that derive from DerivedClass1 d2.derived2_method() # Output: "Derived


class DerivedClass2(DerivedClass1): class 2 method called"

def derived2_method(self):
print("Derived class 2 method called")
Output

Super Class method called


Derived class 1 method called
Derived class 2 method called

In the above example, DerivedClass2 is derived from DerivedClass1, which is


derived from SuperClass.

It means that DerivedClass2 inherits all the attributes and methods of both
DerivedClass1 and SuperClass.

Hence, we are using d2 (object of DerivedClass2) to call methods from


SuperClass, DerivedClass1, and DerivedClass2.
Polymorphism:

You all must have used GPS for navigating the route, Isn‟t it
amazing how many different routes you come across for the
same destination depending on the traffic, from a
programming point of view this is called „polymorphism‟. It is
one such OOP methodology where one task can be performed
in several different ways. To put it in simple words, it is a
property of an object which allows it to take multiple forms.
62
Polymorphism
• Polymorphism is another important concept of object-
oriented programming. It simply means more than one form.

• That is, the same entity (method or operator or object) can


perform different operations in different scenarios.
class Polygon:
# method to render a shape # create an object of Square
def render(self): s1 = Square()
print("Rendering Polygon...") s1.render()

class Square(Polygon): # create an object of Circle


# renders Square c1 = Circle()
def render(self):
c1.render()
print("Rendering Square...")
Run Code
class Circle(Polygon): Output
# renders circle
def render(self): Rendering Square...
print("Rendering Circle...") Rendering Circle...
• In the above example, we have created a superclass: Polygon
and two subclasses: Square and Circle. Notice the use of the
render() method.

• The main purpose of the render() method is to render the


shape. However, the process of rendering a square is different
from the process of rendering a circle.

• Hence, the render() method behaves differently in different


classes. Or, we can say render() is polymorphic
Polymorphism is of two types:

 Compile-time Polymorphism
 Run-time Polymorphism

66
Compile-time Polymorphism:

A compile-time polymorphism also called as static


polymorphism which gets resolved during the compilation
time of the program. One common example is “method
overloading”

67
Example:

class employee1():
def name(self):
print("Harshit is his name")
def salary(self):
print("3000 is his salary")
def age(self):
print("22 is his age")

class employee2():
def name(self):
print("Rahul is his name")
def salary(self):
print("4000 is his salary")
def age(self):
print("23 is his age")

68
def func(obj)://Method Overloading
obj.name()
obj.salary()
obj.age()

obj_emp1 = employee1()
obj_emp2 = employee2()
func(obj_emp1)
func(obj_emp2)

Output:

Harshit is his name 3000 is


his salary 22 is his age
Rahul is his name 4000 is
his salary 23 is his age
23
Run-time Polymorphism:

A run-time Polymorphism is also, called as dynamic


polymorphism where it gets resolved into the run time. One
common example of Run-time polymorphism is “method
overriding”.

70
Example:

class employee():
def init (self,name,age,id,salary):
self.name = name
self.age = age
self.salary = salary
self.id = id
def earn(self):
pass

class childemployee1(employee):
def earn(self): //Run-time polymorphism
print("no money")

71
class childemployee2(employee):
def earn(self):
print("has money")

c = childemployee1
c.earn(employee)
d = childemployee2
d.earn(employee)

Output:

no money,
has money

72
Abstraction:

Suppose you booked a movie ticket from bookmyshow using


net banking or any other process. You don‟t know the
procedure of how the pin is generated or how the verification
is done. This is called „abstraction‟ from the programming
aspect, it basically means you only show the implementation
details of a particular process and hide the details from the
user.

73
Method Overriding in Python Inheritance

• In the previous example, we see the object of the


subclass can access the method of the superclass.

• However, what if the same method is present in both


the superclass and subclass?

• In this case, the method in the subclass overrides the


method in the superclass.

• This concept is known as method overriding in


Python.
#Example: Method Overriding

class Animal:
# attributes and method of the parent class
name = ""

def eat(self): # create an object of the subclass


print("I can eat") labrador = Dog()

# inherit from Animal # call the eat() method on the labrador


class Dog(Animal): object
labrador.eat()
# override eat() method
def eat(self):
print("I like to eat bones")
The super() Method in Python Inheritance
• Previously we saw that the same # inherit from Animal
method in the subclass overrides the class Dog(Animal):
method in the superclass.
# override eat() method
• However, if we need to access the def eat(self):
superclass method from the subclass,
we use the super() method. For # call the eat() method of the superclass
example, using super()
super().eat()
class Animal:
name = "" print("I like to eat bones")
# create an object of the subclass
def eat(self): labrador = Dog()
labrador.eat()
print("I can eat")
Uses of Inheritance:

• Since a child class can inherit all the functionalities of the


parent's class, this allows code reusability.
• Once a functionality is developed, you can simply inherit
it. No need to reinvent the wheel. This allows for cleaner
code and easier to maintain.
• Since you can also add your own functionalities in the
child class, you can inherit only the useful functionalities
and define other required features.
Method Resolution Order (MRO)
class SuperClass1:
in Python def info(self):
If two superclasses have the same method print("Super Class 1 method called")
name and the derived class calls that method,
Python uses the MRO to search for the right class SuperClass2:
method to call. For example, def info(self):
• Here, SuperClass1 and SuperClass2 both of print("Super Class 2 method called")
these classes define a method info().
• So when info() is called using the d1 object class Derived(SuperClass1, SuperClass2):
of the Derived class, Python uses the MRO pass
to determine which method to call.
• In this case, the MRO specifies that d1 = Derived()
methods should be inherited from the d1.info()
leftmost superclass first, so info() of
SuperClass1 is called rather than that of # Output:
SuperClass2. "Super Class 1 method called"
Operator Overloading in Python
 Operator Overloading means giving extended meaning
beyond their predefined operational meaning.
 For example operator + is used to add two integers as
well as join two strings and merge two lists.
 It is achievable because ‘+’ operator is overloaded by
int class and str class.
 You might have noticed that the same built-in operator
or function shows different behavior for objects of
different classes, this is called Operator Overloading.
Operator Overloading in Python
# Python program to show use of
# + operator for different purposes.
print(1 + 2)
Output
# concatenate two strings
print("Geeks"+"For")
3
GeeksFor
# Product two numbers
12
print(3 * 4)
GeeksGeeksGeeksGeeks
# Repeat the String
print("Geeks"*4)
How to overload the operators in Python?
 The two objects which are a physical representation of a class (user-
defined data type) and we have to add two objects with binary ‘+’ operator
it throws an error, because compiler don’t know how to add two objects.
 So we define a method for an operator and that process is called operator
overloading. We can overload all existing operators but we can’t create a
new operator.
 To perform operator overloading, Python provides some special function
or magic function that is automatically invoked when it is associated with
that particular operator.

 For example, when we use + operator, the magic method _add_ is


automatically invoked in which the operation for + operator is defined.
Overloading binary + operator in Python:
• When we use an operator on user-defined data types then
automatically a special function or magic function associated with
that operator is invoked.
• Changing the behavior of operator is as simple as changing the
behavior of a method or function.
• You define methods in your class and operators work according to
that behavior defined in methods.
• When we use + operator, the magic method _add_ is
automatically invoked in which the operation for + operator is
defined.
• Thereby changing this magic method’s code, we can give extra
meaning to the + operator.
How Does the Operator Overloading Actually
work?

Whenever you change the behavior of the existing


operator through operator overloading, you have to
redefine the special function that is invoked automatically
when the operator is used with the objects.
# Python Program illustrate how
# to overload an binary + operator ob3 = A(“VIT ")
# And how it actually works
ob4 = A(“UNIVERSITY BHOPAL")
class A:
def _init_ (self, a): print(ob1 + ob2)
self.a = a
print(ob3 + ob4)

# adding two objects # Actual working when Binary Operator is used.


print(A._add_(ob1 , ob2))
print(A._add_(ob3,ob4))
def _add_ (self, o):
return self.a + o.a #And can also be Understand as :
print(ob1._add_(ob2))
print(ob3._add_(ob4))
ob1 = A(1)
ob2 = A(2)
Explanation:

• We defined the special function “_add( )” and when the


objects ob1 and ob2 are coded as “ob1 + ob2“,

• the special function is automatically called as ob1.add(ob2)


which simply means that ob1 calls the __add( ) function with
ob2 as an Argument and It actually means A .add_(ob1, ob2).

• Hence, when the Binary operator is overloaded, the object


before the operator calls the respective function with object
after operator as parameter.
# Python Program to perform addition
# of two complex numbers using binary
Ob1 = complex(1, 2)
# + operator overloading.
class complex: Ob2 = complex(2, 3)
def _init_(self, a, b):
self.a = a Ob3 = Ob1 + Ob2
self.b = b
print(Ob3)
# adding two objects
def _add_(self, other): Output
return self.a + other.a, self.b + other.b (3, 5)
#Overloading comparison
operators in Python : if(self.a>other.a):
# Python program to overload return True
# a comparison operators else:
return False
class A:
ob1 = A(2) Output:
def _init_(self, a):
ob2 = A(3) ob2 is greater than ob1
self.a = a
if(ob1>ob2):
def _gt_(self, other): print("ob1 is greater than ob2")
else:
print("ob2 is greater than ob1")
Overloading equality and less than
operators: ob1 = A(2)
if(self.a<other.a):
ob2 = A(3)
# Python program to overload equality return "ob1 is lessthan ob2"
# and less than operators
else: print(ob1 < ob2)

return "ob2 is less than ob1"


class A:
ob3 = A(4)
def _eq_(self, other):
def _init_(self, a):
if(self.a == other.a): ob4 = A(4)
self.a = a
return "Both are equal" print(ob1 == ob2)
def _lt_(self, other): else:
Output:
return "Not equal" ob1 is lessthan ob2
Not equal
# Overloading ~ operator, but with
# Python program which attempts two operands
to
# overload ~ operator as binary def _invert_(self):
operator
return "This is the ~ operator,
class A: overloaded as binary operator."
def _init_(self, a): ob1 = A(2)
print(~ob1)
self.a = a
Output
This is the ~ operator, overloaded
as binary operator
operator overloading on Boolean values:
In Python, you can overload the Boolean operators and, or, and not by defining
the _and, __or, and __not_ special methods in your class.
Here’s an example of how to overload the and operator for a custom class:
class MyClass:
def _init_(self, value):
self.value = value

def _and_(self, other):


return MyClass(self.value and other.value)

a = MyClass(True)
b = MyClass(False)

c = a & b # c.value is False


Advantages of operator overloading
• Overloading boolean operators in a custom class can provide several advantages, including:Improved
readability:
• By overloading boolean operators, you can provide a more natural syntax and semantics for your class
that makes it easier to read and understand.
• Consistency with built-in types: Overloading boolean operators can make your class behave more like
built-in types in Python, which can make it easier to use and integrate with other code.
• Operator overloading: Overloading boolean operators is an example of operator overloading in
Python, which can make your code more concise and expressive by allowing you to use familiar
operators to perform custom operations on your objects.
• Custom behavior: Overloading boolean operators can allow you to define custom behavior for your
class that is not available in built-in types or other classes.
• Enhanced functionality: By overloading boolean operators, you can add new functionality to your
class that was not available before, such as the ability to perform logical and or or operations on
instances of your class.
• Overall, overloading boolean operators in a custom class can make your code more readable,
consistent, concise, expressive, and functional.
• However, it’s important to use operator overloading judiciously and only when it makes sense for the
semantics of your class.
Explanation:
• In this example, we define a MyClass that has a single attribute value, which is a
boolean.
• We then overload the & operator by defining the _and_ method to perform a
logical and operation on the value attribute of two MyClass instances.
• When we call a & b, the _and_ method is called with a as the first argument and
b as the second argument.
• The method returns a new instance of MyClass with a value attribute that is the
logical and of a.value and b.value.
• Note that Python also provides built-in boolean operators that can be used with
any object.
• For example, you can use the bool() function to convert any object to a boolean
value, and the all() and any() functions to perform logical and and or operations
on a sequence of boolean values.
• Overloading the boolean operators in a custom class can be useful to provide a
more natural syntax and semantics for your class.
Difference between Method Overloading and Method
Overriding in Python
Method Overloading:
• Method Overloading is an example of Compile time
polymorphism.
• In this, more than one method of the same class shares the same
method name having different signatures.
• Method overloading is used to add more to the behavior of
methods and there is no need of more than one class for method
overloading.
• Note: Python does not support method overloading. We may
overload the methods but can only use the latest defined method.
# if datatype is str # Integer
# initialize answer as '' add('int', 5, 6)
# Function to take
multiple arguments if datatype =='str': # String
answer ='' add('str', ‘VIT ', ‘BHOPAL')
def add(datatype, *args):
# Traverse through the arguments
# if datatype is int for x in args: Output:
# initialize answer as 0 11
# This will do addition if the VIT BHOPAL
if datatype =='int': # arguments are int. Or concatenation
answer = 0 # if the arguments are str

answer = answer + x
print(answer)
Difference between Method Overloading and Method Overriding in Python:
Method Overriding:
 Method overriding is an example of run time polymorphism.

 In this, the specific implementation of the method that is already


provided by the parent class is provided by the child class.

 It is used to change the behavior of existing methods and there is a


need for at least two classes for method overriding.

 In method overriding, inheritance always required as it is done between


parent class(superclass) and child class(child class) methods.
Abstract Classes in Python:

An abstract class is the class which contains one or more


abstract methods. An abstract method is the one which is just
defined but not implemented.

• What is an Abstract Class in Python?


• Types of Methods in Python based on the Implementation
• How to declare an abstract method in Python
• Abstract Classes in Python
• Can abstract classes contain more sub classes?
• Different cases for Abstract class object creation.
Types of Methods in Python:

Abstract Class in Python has 2 types


based on the implementation the
methods can be divided into two types:

1. Implemented methods.
2. Un-implemented method.
Abstract Class in Python has 2 types based on the implementation,
1. Implemented methods:
• A method which has a both method name and method body,
that method is called an implemented method.
• They are also called concrete methods or non-abstract
methods. The methods which we have seen in the previous
chapters are implemented i.e having method name and body
as well.
2. Un-implemented methods:
• A method which has only method name and no method body,
that method is called an unimplemented method.
• They are also called as non-concrete or abstract methods.
How to declare an abstract method in Python:
Abstract methods, in python, are declared by using
@abstractmethod decorator.

class Demo: • Method ‘one’ is abstract method.


@abstractmethod
• Method ‘two’ is non-abstract
def one(self):
method.
pass
• Since one abstract method is present
def two(self): in class ‘Demo’, it is called Abstract
Print("ImplimenteMethod") class
Abstract Method in Python
• From the above example, we can understand that an abstract
class is the one which does not have implementation.
• Few points about it: By using @abstractmethod decorator we can
declare a method as an abstract method.
• @abstractmethod decorator presents in abc module.
• We should import the abc module in order to use the decorator.
• Since abstract method is an unimplemented method, we need to
put a pass statement, else it will result in error.
• Class which contains abstract methods is called an abstract class.
• For abstract methods, implementation must be provided in the
subclass of abstract class.
#Python demo Program to show abstract methods
# Example Program: Abstract methods

from abc import *


class Demo1(ABC): Output:
@abstractmethod
def m1(self): No Output because no
pass object is created.
@abstractmethod
def m2(self):
pass
def m3(self):
print("Implemented method")
# Example Program Abstract Class:
from abc import ABC, abstractmethod
Output:
#Abstract Class
class Bank(ABC): Abstract Classes in Python
def bank_info(self):
print("Welcome to bank")
@abstractmethod • In the above example, Bank is an
def interest(self): abstract class which having intertest()
"Abstarct Method" abstract method.
pass • SBI class is a child class to Bank class, so
SBI class should provide implementation
#Sub class/ child class of abstract class
class SBI(Bank): for abstract method which is available in
def interest(self): Bank abstract class.
"Implementation of abstract method" • An object is created to subclass, which is
print("In sbi bank 5 rupees interest") SBI, and the implemented method
s= SBI() interest() is called.
s.bank_info ()
s.interest()
Iterators

>>> it.next()
‟c‟

>>> it.next()
Traceback (most recent call last):
File "<pyshell#6>", line 1, in -toplevel
it.next()
StopIteration
Iterators

Having seen the mechanics behind the iterator protocol, it


is easy to add iterator behavior to our classes.

Define a __iter__() method which returns an object with a


next() method.

If the class defines next(), then __iter__() can just return


self:
Iterators

>>> class Reverse:


"Iterator for looping over a sequence backwards"
def __init__(self, data):
self.data = data
self.index = len(data)
def __iter__(self):
return self
Iterators

def next(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.data[self.index]
Iterators

>>> for char in Reverse(‟spam‟):


print char
m
a
p
s
Generators
• Generators are a simple and powerful tool for
creating iterators.

• They are written like regular functions but use the


yield statement whenever they want to return data.

• Each time the next() is called, the generator resumes


where it left-off (it remembers all the data values
and which statement was last executed).

• An example shows that generators can be trivially


easy to create:
Generators

>>> def reverse(data):


for index in range(len(data)-1, -1, -1):
yield data[index]
>>> for char in reverse(‟golf‟):
print char
f
l
o
g
Generators

• Anything that can be done with generators can also be done with
class based iterators as described in the previous section.
• What makes generators so compact is that the __iter__() and
next() methods are created automatically.
• Another key feature is that the local variables and execution state
are automatically saved between calls.
• This made the function easier to write and much more clear than
an approach using class variables like self.index and self.data.
Generators

• In addition to automatic method creation and saving


program state, when generators terminate, they
automatically raise StopIteration.

• In combination, these features make it easy to create


iterators with no more effort than writing a regular
function.
Unit. 3 Python Programming
 Principles of Object Orientation,
 Classes in Python,
 Creating
 Classes,
 Instance Methods,
 Access Specification,
 data modeling,
 persistent storage of objects,
 inheritance, polymorphism,
 operator overloading,
 abstract classes,
• exception handling,
• try block
Exception Handling

• Exceptions occur when certain exceptional situations


occur in our program.
• For example, what if we are reading a file and we
accidentally deleted it in another window or some other
error occurred? Such situations are handled using
exceptions.
• What if our program had some invalid statements?
• This is handled by Python which raises its hands and tells
you there is an error.
Exception Handling
Consider a simple print statement.
What if we misspelt print as Print?
Note the capitalization.
In this case, Python raises a syntax error.
>>> Print 'Hello, World' File "<stdin>", line 1 Print 'Hello, World' ^
SyntaxError: invalid syntax
>>> print 'Hello, World'
Hello, World
>>>
Observe that a SyntaxError is raised and also the location where the error
was detected, is printed. This is what a handler for the error does.
Exception Handling
To show the usage of exceptions, we will try to read input
from the user and see what happens.

>>> s = raw_input('Enter something --> ')

Enter something --> Traceback (most recent call last): File


"<stdin>", line 1, in ? EOFError

>>>
Here, we ask the user for input and if he/she presses Ctrl-d
i.e. the EOF (end of file) character, then Python raises an
error called EOFError.

Next, we will see how to handle such errors.


Exception Handling

• We can handle exceptions using the try..except


statement.

• We basically put our usual statements within the


try-block.

• And we put all the error handlers in the except-


block.
Exception Handling

import sys
try:
s = raw_input('Enter something --> ')
except EOFError:
print '\nWhy did you do an EOF on me?' sys.exit() # Exit the program
except:
print '\nSome error/exception occurred.'
# Here, we are not exiting the program
print 'Done'
Exception Handling
• We put all the statements that might raise an error in the
try block

• And then handle all errors and exceptions in the except


clause/block.

• The except clause can handle a single specified error or


exception or a parenthesized list of errors/exceptions.

• If no names of errors or exceptions are supplied, it will


handle all errors and exceptions.

• There has to be at least one except clause associated with


every try clause.
Exception Handling

• If any error or exception is not handled, then the default


Python handler is called which stops the execution of the
program and prints a message.

• We can also have an else clause with the try..catch block.

• The else clause is executed if no exception occurs.

• We can also get the exception object so that we can retrieve


additional information about the exception which has occurred.

• This is demonstrated in the next example.


Exception Handling

We can raise exceptions using the raise statement


- we specify the name of the error/exception and the exception
object.

The error or exception that we can raise should be a class which


directly or indirectly is a derived class of the Error or Exception class
respectively.
Exception Handling

class ShortInputException(Exception):
'''A user-defined exception class.'''
def __init__(self, length, atleast):
self.length = length
self.atleast = atleast
try:
s = raw_input('Enter something --> ')
if len(s) < 3:
raise ShortInputException(len(s), 3)
Exception Handling

Other work can go as usual here. except


EOFError:
print '\nWhy did you do an EOF on me?‘
except ShortInputException, x:
print ‘ \nThe input was of length %d, it should be at least
%d'\ % (x.length, x.atleast)
else:
print 'No exception was raised.'
Exception Handling

Other work can go as usual here. except EOFError:


print '\nWhy did you do an EOF on me?‘
except ShortInputException, x:
print ‘ \nThe input was of length %d, it should be at least %d'\ %
(x.length, x.atleast)
else:
print 'No exception was raised.'
Exception Handling

What if we wanted some statements to execute after the


try block whether or not an exception was raised?

This is done using the finally block.

Note that if we are using a finally block, we cannot have


any except clauses for the same try block.
Exception Handling
try:
f = file('poem.txt')
while True: # Our usual file-reading block
l = f.readline()
if len(l) == 0:
break
print l,
finally:
print 'Cleaning up...'
f.close()
Unit Summary 3 Python Programming
 Principles of Object Orientation,
 Classes in Python,
 Creating
 Classes,
 Instance Methods,
 Access Specification,
 data modeling,
 persistent storage of objects,
 inheritance, polymorphism,
 operator overloading,
 abstract classes,
• exception handling,
• try block

You might also like