0% found this document useful (0 votes)
3 views22 pages

Introdcution To Python Programming Notes - Unit - IV

The document discusses polymorphism in Python, explaining its ability to allow objects to take on multiple forms and perform actions in different ways. It covers examples of polymorphism through built-in functions like len(), operator overloading, and method overriding in inheritance, highlighting how methods can be redefined in child classes. Additionally, it addresses method overloading and the limitations in Python, providing examples to illustrate these concepts.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views22 pages

Introdcution To Python Programming Notes - Unit - IV

The document discusses polymorphism in Python, explaining its ability to allow objects to take on multiple forms and perform actions in different ways. It covers examples of polymorphism through built-in functions like len(), operator overloading, and method overriding in inheritance, highlighting how methods can be redefined in child classes. Additionally, it addresses method overloading and the limitations in Python, providing examples to illustrate these concepts.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

4.

Introduction:
Polymorphism in Python is the ability of an object to take many forms. In simple words,
polymorphism allows us to perform the same action in many different ways.

For example, Jessa acts as an employee when she is at the office. However, when she is at home,
she acts like a wife. Also, she represents herself differently in different places. Therefore, the same
person takes different forms as per the situation.

A person takes different forms. In polymorphism, a method can process objects differently
depending on the class type or data type. Let’s see simple examples to understand it better.

Polymorphism in Built-in function len()


The built-in function len() calculates the length of an object depending upon its type. If an object is
a string, it returns the count of characters, and If an object is a list, it returns the count of items in a
list.
The len() method treats an object as per its class type.
Example:

students = ['Emma', 'Jessa', 'Kelly']


school = 'ABC School'

# calculate count
print(len(students))
print(len(school))

Output

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV - 1


10

Polymorphic len() function

4.1 Operator Overloading in Python:


Operator overloading means changing the default behavior of an operator depending on the
operands (values) that we use. In other words, we can use the same operator for multiple purposes.
For example, the + operator will perform an arithmetic addition operation when used with numbers.
Likewise, it will perform concatenation when used with strings. The operator + is used to carry out
different operations for distinct data types. This is one of the most simple occurrences of
polymorphism in Python.
Example:

# add 2 numbers
print(100 + 200)

# concatenate two strings


print('Jess' + 'Roy')

# merger two list


print([10, 20, 30] + ['jessa', 'emma', 'kelly'])

Output:

300
JessRoy
[10, 20, 30, 'jessa', 'emma', 'kelly']

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV - 2


Overloading + operator for custom objects
Suppose we have two objects, and we want to add these two objects with a binary + operator.
However, it will throw an error if we perform addition because the compiler doesn’t add two
objects. See the following example for more details.
Example:

class Book:
def init (self, pages):
[Link] = pages

# creating two objects


b1 = Book(400)
b2 = Book(300)

# add two objects


print(b1 + b2)

Output

TypeError: unsupported operand type(s) for +: 'Book' and 'Book'

We can overload + operator to work with custom objects also. Python provides some special or
magic function that is automatically invoked when associated with that particular operator.
For example, when we use the + operator, the magic method add () is automatically invoked.
Internally + operator is implemented by using add () method. We have to override this method
in our class if you want to add two custom objects.
Example:

class Book:
def init (self, pages):
[Link] = pages

# Overloading + operator with magic method


def add (self, other):
return [Link] + [Link]

b1 = Book(400)
b2 = Book(300)
print("Total number of pages: ", b1 + b2)

Output

Total number of pages: 700

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV - 3


ANURAG UNIVERSITY

Example Code:
# Python Program to perform addition
# of two complex numbers using
binary # + operator overloading.
class complex:
def init (self, a, b):
self.a = a
self.b = b
# adding two objects
def add (self, other):
return self.a + other.a, self.b + other.b
def str (self):
return self.a, self.b
Ob1 = complex(1, 2)
Ob2 = complex(2, 3)
Ob3 = Ob1 + Ob2
print(Ob3)
Output :
(3, 5)

Overloading the * Operator

The * operator is used to perform the multiplication. Let’s see how to overload it to calculate the
salary of an employee for a specific period. Internally * operator is implemented by using
the mul () method.
Example:

class Employee:
def init (self, name, salary):
[Link] = name
[Link] = salary

def mul (self, timesheet):


print('Worked for', [Link], 'days')
# calculate salary
return [Link] * [Link]

class TimeSheet:
def init (self, name, days):
[Link] = name
[Link] = days

emp = Employee("Jessa", 800)


timesheet = TimeSheet("Jessa", 50)

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV - 4


ANURAG UNIVERSITY
print("salary is: ", emp * timesheet)

Output
Wroked for 50 days
salary is: 40000

Magic Methods
In Python, there are different magic methods available to perform overloading operations. The
below table shows the magic methods names to overload the mathematical operator, assignment
operator, and relational operators in Python.
Operator Name Symbol Magic method

Addition + add (self, other)

Subtraction - sub (self, other)

Multiplication * mul (self, other)

Division / div (self, other)

Floor Division // floordiv (self,other)

Modulus % mod (self, other)

Power ** pow (self, other)

Increment += iadd (self, other)

Decrement -= isub (self, other)

Product *= imul (self, other)

Division /+ idiv (self, other)

Modulus %= imod (self, other)

Power **= ipow (self, other)

Less than < lt (self, other)

Greater than > gt (self, other)

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV - 5


ANURAG UNIVERSITY
Operator Name Symbol Magic method

Less than or equal to <= le (self, other)

Greater than or equal to >= ge (self, other)

Equal to == eq (self, other)

Not equal != ne (self, other)

4.2 Polymorphism With Inheritance:


Polymorphism is mainly used with inheritance. In inheritance, child class inherits the attributes
and methods of a parent class. The existing class is called a base class or parent class, and the new
class is called a subclass or child class or derived class.
Using method overriding polymorphism allows us to defines methods in the child class that have
the same name as the methods in the parent class. This process of re-implementing the inherited
method in the child class is known as Method Overriding.

Advantage of method overriding

 It is effective when we want to extend the functionality by altering the inherited method. Or
the method inherited from the parent class doesn’t fulfill the need of a child class, so we
need to re-implement the same method in the child class in a different way.
 Method overriding is useful when a parent class has multiple child classes, and one of that
child class wants to redefine the method. The other child classes can use the parent class
method. Due to this, we don’t need to modification the parent class code

Key features of Method Overriding in Python


These are some of the key features and advantages of method overriding in Python --

 Method Overriding is derived from the concept of object oriented programming


 Method Overriding allows us to change the implementation of a function in the child class
which is defined in the parent class.
 Method Overriding is a part of the inheritance mechanism
 Method Overriding avoids duplication of code
 Method Overriding also enhances the code adding some additional properties.

Prerequisites for method overriding


There are certain prerequisites for method overriding in Python. They're discussed below --

1. Method overriding cannot be done within a class. So,we need to derive a child class from a
parent class. Hence Inheritance is mandatory.

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV - 6


ANURAG UNIVERSITY
2. The method must have the same name as in the parent class
3. The method must have the same number of parameters as in the parent class.

In polymorphism, Python first checks the object’s class type and executes the appropriate method
when we call the method. For example, If you create the Car object, then Python calls the
speed() method from a Car class.
Let’s see how it works with the help of an example.

Example: Method Overriding


In this example, we have a vehicle class as a parent and a ‘Car’ and ‘Truck’ as its sub-class. But each
vehicle can have a different seating capacity, speed, etc., so we can have the same instance method
name in each class but with a different implementation. Using this code can be extended and easily
maintained over time.

Pol
ymorphism with Inheritance

class Vehicle:

def init (self, name, color, price):


[Link] = name
[Link] = color
[Link] = price

def show(self):
print('Details:', [Link], [Link], [Link])

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV - 7


ANURAG UNIVERSITY

def max_speed(self):
print('Vehicle max speed is 150')

def change_gear(self):
print('Vehicle change 6 gear')

# inherit from vehicle class


class Car(Vehicle):
def max_speed(self):
print('Car max speed is 240')

def change_gear(self):
print('Car change 7 gear')

# Car Object
car = Car('Car x1', 'Red', 20000)
[Link]()
# calls methods from Car class
car.max_speed()
car.change_gear()

# Vehicle Object
vehicle = Vehicle('Truck x1', 'white', 75000)
[Link]()
# calls method from a Vehicle class
vehicle.max_speed()
vehicle.change_gear()

Output:

Details: Car x1 Red 20000


Car max speed is 240
Car change 7 gear

Details: Truck x1 white 75000


Vehicle max speed is 150
Vehicle change 6 gear

As you can see, due to polymorphism, the Python interpreter recognizes that
the max_speed() and change_gear() methods are overridden for the car object. So, it uses the one
defined in the child class (Car)
On the other hand, the show() method isn’t overridden in the Car class, so it is used from the
Vehicle class.

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV - 8


ANURAG UNIVERSITY

Overrride Built-in Functions


In Python, we can change the default behavior of the built-in functions. For example, we can
change or extend the built-in functions such as len(), abs(), or divmod() by redefining them in our
class. Let’s see the example.
Example
In this example, we will redefine the function len()

class Shopping:
def init (self, basket, buyer):
[Link] = list(basket)
[Link] = buyer

def len (self):


print('Redefine length')
count = len([Link])
# count total items in a different way
# pair of shoes and shir+pant
return count * 2

shopping = Shopping(['Shoes', 'dress'], 'Jessa')


print(len(shopping))

Output

Redefine length
4

Polymorphism In Class methods


Polymorphism with class methods is useful when we group different objects having the same
method. we can add them to a list or a tuple, and we don’t need to check the object type before
calling their methods. Instead, Python will check object type at runtime and call the correct method.
Thus, we can call the methods without being concerned about which class type each object is. We
assume that these methods exist in each class.
Python allows different classes to have methods with the same name.

 Let’s design a different class in the same way by adding the same methods in two or more
classes.
 Next, create an object of each class
 Next, add all objects in a tuple.
 In the end, iterate the tuple using a for loop and call methods of a object without checking
its class.
Example

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV - 9


ANURAG UNIVERSITY
In the below example, fuel_type() and max_speed() are the instance methods created in both
classes.

class Ferrari:
def fuel_type(self):
print("Petrol")

def max_speed(self):
print("Max speed 350")

class BMW:
def fuel_type(self):
print("Diesel")

def max_speed(self):
print("Max speed is 240")

ferrari = Ferrari()
bmw = BMW()

# iterate objects of same type


for car in (ferrari, bmw):
# call methods without checking class of object
car.fuel_type()
car.max_speed()

Output
Petrol
Max speed 350

Diesel
Max speed is 240

As you can see, we have created two classes Ferrari and BMW. They have the same instance
method names fuel_type() and max_speed(). However, we have not linked both the classes nor
have we used inheritance.
We packed two different objects into a tuple and iterate through it using a car variable. It is possible
due to polymorphism because we have added the same method in both classes Python first checks
the object’s class type and executes the method present in its class.

Polymorphism with Function and Objects


We can create polymorphism with a function that can take any object as a parameter and execute its
method without checking its class type. Using this, we can call object actions using the same
function instead of repeating method calls.
Example

class Ferrari:

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV- 10


ANURAG UNIVERSITY
def fuel_type(self):
print("Petrol")

def max_speed(self):
print("Max speed 350")

class BMW:
def fuel_type(self):
print("Diesel")

def max_speed(self):
print("Max speed is 240")

# normal function
def car_details(obj):
obj.fuel_type()
obj.max_speed()

ferrari = Ferrari()
bmw = BMW()

car_details(ferrari)
car_details(bmw)

Output

Petrol
Max speed 350
Diesel
Max speed is 240

Polymorphism In Built-in Methods


The word polymorphism is taken from the Greek words poly (many) and morphism (forms). It
means a method can process objects differently depending on the class type or data type.
The built-in function reversed(obj) returns the iterable by reversing the given object. For example,
if you pass a string to it, it will reverse it. But if you pass a list of strings to it, it will return the
iterable by reversing the order of elements (it will not reverse the individual string).
Let us see how a built-in method process objects having different data types.
Example:

students = ['Emma', 'Jessa', 'Kelly']


school = 'ABC School'

print('Reverse string')
for i in reversed('PYnative'):
print(i, end=' ')

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV- 11


ANURAG UNIVERSITY

print('\nReverse list')
for i in reversed(['Emma', 'Jessa', 'Kelly']):
print(i, end=' ')

Output:
Reverse string
evitanYP

Reverse list
Kelly Jessa Emma

Method Overloading
The process of calling the same method with different parameters is known as method overloading.
Python does not support method overloading. Python considers only the latest defined method even
if you overload the method. Python will raise a TypeError if you overload the method.
Example

def addition(a, b):


c=a+b
print(c)

def addition(a, b, c):


d=a+b+c
print(d)

# the below line shows an error


# addition(4, 5)

# This line will call the second product method


addition(3, 7, 5)

To overcome the above problem, we can use different ways to achieve the method overloading. In
Python, to overload the class method, we need to write the method’s logic so that different code
executes inside the function depending on the parameter passes.
For example, the built-in function range() takes three parameters and produce different result
depending upon the number of parameters passed to it.
Example:

for i in range(5): print(i, end=', ')


print()
for i in range(5, 10): print(i, end=', ')

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV- 12


ANURAG UNIVERSITY
print()
for i in range(2, 12, 2): print(i, end=', ')

Output:
0, 1, 2, 3, 4,
5, 6, 7, 8, 9,
2, 4, 6, 8, 10,

Let’s assume we have an area() method to calculate the area of a square and rectangle. The method
will calculate the area depending upon the number of parameters passed to it.

 If one parameter is passed, then the area of a square is calculated


 If two parameters are passed, then the area of a rectangle is calculated.

Example: User-defined polymorphic method

class Shape:
# function with two default parameters
def area(self, a, b=0):
if b > 0:
print('Area of Rectangle is:', a * b)
else:
print('Area of Square is:', a ** 2)

square = Shape()
[Link](5)

rectangle = Shape()
[Link](5, 3)

Output:

Area of Square is: 25


Area of Rectangle is: 15

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV- 13


ANURAG UNIVERSITY

4. .4 EXCEPTION HANDLING:

Introduction:

Errors are nothing but mistakes in the code which are potentially harmful.
Errors and exceptions:
Errors or mistakes in a program are often referred to as bugs. They are almost always the
fault of the programmer. The process of finding and eliminating errors is called debugging. Errors
can be classified into three major groups:
1.
2. Syntax errors
3. Runtime errors
4. Logical errors

4.4.1 Syntax errors:


Python will find these kinds of errors when it tries to parse your program, and exit with an
error message without running anything. Syntax errors are mistakes in the use of the Python
language, and are analogous to spelling or grammar mistakes in a language like English.
Common Python syntax errors include:
1. leaving out a keyword
2. putting a keyword in the wrong place
3. leaving out a symbol, such as a colon, comma or brackets
4. misspelling a keyword
5. incorrect indentation
6. empty block
Python will do its best to tell you where the error is located, but sometimes its messages can be
misleading: for example, if you forget to escape a quotation mark inside a string you may get a
syntax error referring to a place later in your code, even though that is not the real source of the
problem.
Here are some examples of syntax errors in Python:
myfunction(x, y):
return x + y

else:
print("Hello!")

if mark >= 50
print("You passed!")

if arriving:
print("Hi!")
esle:
print("Bye!")

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV- 14


ANURAG UNIVERSITY
if flag:
print("Flag is set!")

4.4.2 Runtime errors:


If a program is syntactically correct – that is, free of syntax errors – it will be run by the
Python interpreter. However, the program may exit unexpectedly during execution if it encounters
a runtime error – a problem which was not detected when the program was parsed, but is only
revealed when a particular line is executed. When a program comes to a halt because of a runtime
error, we say that it has crashed.
Some examples of Python runtime errors:
1. division by zero
2. performing an operation on incompatible types
3. using an identifier which has not been defined
4. accessing a list element, dictionary value or object attribute which doesn’t exist
5. trying to access a file which doesn’t exist
Runtime errors often creep in if you don’t consider all possible values that a variable could contain,
especially when you are processing user input. You should always try to add checks to your code to
make sure that it can deal with bad input and edge cases gracefully.
4.4.3 Logical errors:
Logical errors are the most difficult to fix. They occur when the program runs without crashing, but
produces an incorrect result. The error is caused by a mistake in the program’s logic. You won’t get
an error message, because no syntax or runtime error has occurred. You will have to find the
problem on your own by reviewing all the relevant parts of your code – although some tools can
flag suspicious code which looks like it could cause unexpected behaviour.
Sometimes these kinds of errors are caused by programmer carelessness. Here are some examples
of mistakes which lead to logical errors:
1. using the wrong variable name
2. indenting a block to the wrong level
3. using integer division instead of floating-point division
4. getting operator precedence wrong
5. making a mistake in a boolean expression
6. off-by-one, and other numerical errors

4.5 Excepptions:
An exception can be defined as an abnormal condition in a program resulting in the disruption in
the flow of the program.
An Exception is an error that happens during the execution of a program. Whenever there is an
error, Python generates an exception that could be handled. It basically prevents the program from
getting crashed.
Exceptions are convenient in many ways for handling errors and special conditions in a
program. When you think that you have a code which can produce an error, you can use exception
handling technique.
A list of common exceptions that can be thrown from a normal python program is given below.

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV- 15


ANURAG UNIVERSITY
1. ZeroDivisionError: Occurs when a number is divided by zero.
2. NameError: It occurs when a name is not found. It may be local or global.
3. IndentationError: If incorrect indentation is given.
4. IOError: It occurs when Input Output operation fails.
5. EOFError: It occurs when the end of the file is reached, and yet operations are being
performed.

Python Built-in Exceptions:

Exception Cause of Error

AssertionError Raised when assert statement fails.

AttributeError Raised when attribute assignment or reference fails.

EOFError Raised when the input() functions hits end-of-file condition.

FloatingPointError Raised when a floating point operation fails.

ZeroDivisionError Raised when second operand of division or modulo operation is zero.

ImportError Raised when the imported module is not found.

IndexError Raised when index of a sequence is out of range.

KeyError Raised when a key is not found in a dictionary.

KeyboardInterrupt Raised when the user hits interrupt key (Ctrl+c or delete).

MemoryError Raised when an operation runs out of memory.

NameError Raised when a variable is not found in local or global scope.

NotImplementedError Raised by abstract methods.

OSError Raised when system operation causes system related error.

Raised when result of an arithmetic operation is too large to be


OverflowError represented.

Raised when a weak reference proxy is used to access a garbage collected


ReferenceError referent.

RuntimeError Raised when an error does not fall under any other category.

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV- 16


ANURAG UNIVERSITY
Raised by next() function to indicate that there is no further item to be
StopIteration returned by iterator.

SyntaxError Raised by parser when syntax error is encountered.

IndentationError Raised when there is incorrect indentation.

TabError Raised when indentation consists of inconsistent tabs and spaces.

SystemError Raised when interpreter detects internal error.

SystemExit Raised by [Link]() function.

Raised when a function or operation is applied to an object of incorrect


TypeError type.

Raised when a reference is made to a local variable in a function or


UnboundLocalError method, but no value has been bound to that variable.

UnicodeError Raised when a Unicode-related encoding or decoding error occurs.

UnicodeEncodeError Raised when a Unicode-related error occurs during encoding.

UnicodeDecodeError Raised when a Unicode-related error occurs during decoding.

UnicodeTranslateError Raised when a Unicode-related error occurs during translating.

ValueError Raised when a function gets argument of correct type but improper value.

GeneratorExit Raise when a generator's close() method is called.

4.6 Handling Exceptions:


In Python, exceptions can be handled by two new methods:
 Try: Catches exceptions raised by Python or a program

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV- 17


ANURAG UNIVERSITY
 Raise: A custom exception which triggers an exception
manually

4.6.1 try and except block:

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV- 18


ANURAG UNIVERSITY

Syntax:

try:
#block of code

except Exception1:
#block of code

except Exception2:
#block of code

#other code

We can also use the else statement with the try-except statement in which, we can place the code
which will be executed in the scenario if no exception occurs in the try block.

4.7Multiple Except Blocks:

4.7.1 try and except block with else:

It gets initiated with a try header line which is followed by a block of indented statements and then
by one or more optional except clauses and then at the end an optional else clause can be used as
shown below:
The syntax to use the else statement with the try-except statement is given below.

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV- 19


ANURAG UNIVERSITY
try:
Your statements

except Exception_1:
If there is Exception_1 then execute this block- statement

except Exception_2:
If there is Exception_2 then execute this block-statement

else:
if no exception was raised-statement

Example

try:
a = int(input("Enter a:"))
b = int(input("Enter b:"))
c = a/b;
print("a/b = %d"%c)
except Exception:
print("can't divide by zero")
else:
print("Hi I am else block")

Output:

Enter a:10
Enter b:2
a/b = 5

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV- 20


ANURAG UNIVERSITY
Hi I am else block

4.7.2 Try-finally Clause:

A try statement can have more than once except clause, It can also have optional else
and/or finally statement.
try:
<body>
except <ExceptionType1>:
<handler1>
except <ExceptionTypeN>:
<handlerN>
except:
<handlerExcept>
else:
<process_else>
finally:
<process_finally>
except clause is similar to elif . When exception occurs, it is checked to match the exception type
in except clause. If match is found then handler for the matching case is executed. Also note that in
last except clause ExceptionType is omitted. If exception does not match any exception type
before the last except clause, then the handler for last except clause is executed.

Note: Statements under the else clause run only when no exception is raised.

Note: Statements in finally block will run every time no matter exception occurs or not.

Example:
num1, num2 = eval(input("Enter two numbers, separated by a comma : "))
result = num1 / num2
print("Result is", result)

except ZeroDivisionError:
print("Division by zero is error !!")

except SyntaxError:
print("Comma is missing. Enter numbers separated by comma like this 1, 2")

except:
print("Wrong input")

else:
print("No exceptions")

finally:
print("This will execute no matter what")

4.7.3 Raising exceptions:

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV- 21


ANURAG UNIVERSITY
To raise your exceptions from your own methods you need to use raise keyword like this
raise ExceptionClass("Your argument")

Example:
def enterage(age):
if age < 0:
raise ValueError("Only positive integers are allowed")

if age % 2 == 0:
print("age is even")
else:
print("age is odd")

try:
num = int(input("Enter your age: "))
enterage(num)

except ValueError:
print("Only positive integers are allowed")
except:
print("something is wrong")
Output:
Enter your age: 12
age is even
Enter your age: -12
Only integers are allowed

DEPT. OF. INFORMATION TECHNOLOGY Introduction to Python Programming UNIT-IV- 22

You might also like