0% found this document useful (0 votes)
31 views80 pages

Unit 4 - Files - OOP

This document covers key concepts of file handling and object-oriented programming in Python. It explains file types, operations, paths, and the importance of closing files, along with the fundamentals of classes, objects, and methods in OOP. Additionally, it provides examples of file operations and class definitions to illustrate the concepts discussed.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views80 pages

Unit 4 - Files - OOP

This document covers key concepts of file handling and object-oriented programming in Python. It explains file types, operations, paths, and the importance of closing files, along with the fundamentals of classes, objects, and methods in OOP. Additionally, it provides examples of file operations and class definitions to illustrate the concepts discussed.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 80

Unit 4

Files ,
Object Oriented Programming
Reference Textbook:
Gowrishankar S
Files : topics under this
• File Types;
• Operations on Files–
– Create,
– Open,
– Read,
– Write,
– Close Files;
• File Names and Paths;
• Format Operator.
Note: refer all programs given in class and from journal
FILES
• A file is the common storage unit in a computer, and
all programs and data are “written” into a file and
“read” from a file.
• Every file has a filename and extension (Hello.docx) .
• The file extension helps your computer’s operating
system, like Windows, determine which program will
be associated with the file.
• Files contain data and directories contain groups of
files and organize them on the hard disk.
• Directories dont occupy space but files occupy from
few bytes to GB.
Types of files
• There are 2 types of files in python
1) Text files
2) Binary files

1) Text files :
• Text files contain only textual data
• A typical plain text file contains several lines of text that
are each followed by an End-of-Line (EOL) character.
• An End-of-File (EOF) marker is placed after the final
character, which signals the end of the file.
• Text files include a character encoding scheme that
determines how the characters are interpreted and what
characters can be displayed.
• Common text editors are Notepad, wordpad, textedit etc
• Common extensions for text file formats:
– Web standards: html, xml, css, svg, json,...
– Source code: c, cpp, h, cs, js, py, java, rb, pl, php,
sh,...
– Documents: txt, tex, markdown, asciidoc, rtf, ps,...
– Configuration: ini, cfg, rc, reg,...
– Tabular data: csv, tsv,..
2) Binary files:
• Binary files typically contain a sequence of bytes
or ordered groupings of eight bits.
• Binary file format can store multiple types of
data like images, audio, video in a single file.
• This data can be interpreted by supporting
programs but will show up as garbled text in a
text editor.
• Binary files contain headers in readable form
that give information about file type and other
description. If the header contains invalid data
then the file becomes corrupt or cannot be
opened.
• Common extensions for binary file formats:
– Images: jpg, png, gif, bmp, tiff, psd,...
– Videos: mp4, mkv, avi, mov, mpg, vob,...
– Audio: mp3, aac, wav, flac, ogg, mka, wma,...
– Documents: pdf, doc, xls, ppt, docx, odt,...
– Archive: zip, rar, 7z, tar, iso,...
– Database: mdb, accde, frm, sqlite,...
– Executable: exe, dll, so, class,...
File paths
• File path is basically a route so that the user or
the program knows where the file is located.
• To use files we must specify its path
• The path to a specified file consists of one or
more components, separated by a special
character (a backslash for Windows and forward
slash for Linux).
• each component is usually a directory name or
file name, or drive name in Windows or root in
Linux.
• example: D:\\myfiles\python\home.py
There are 2 types of file paths : Fully qualified and
Relative
• Fully qualified file path (Absolute path) :
– it points to the file location, which always contains the root and the
complete directory list.
– The current directory is the directory in which a user is working at a
given time.
– Example : D:\\myfiles\python\home.py or D:\\ welcome.txt

• Relative path :
– It consists of two consecutive dots or a single dot as one of the
components in a path.
– These dots denote the directory above the current directory (parent
directory)
– Example : ..\home.py or ..\..\home.py or .\home.py
Different operations on files and their
respective functions
1) Open a file  open() , with open()
2) Read data from file  read() , readline(),
readlines()
3) Write data to a file  write() , writelines()
4) Close a file  close()
5) Delete a file  os.remove()
6) Move the file handler  seek()
7) display the current position of file handler 
tell()
1. Creating and opening text files
• Before we perform any read or write operation , we
must open the file using the python builtin function
open() .
• When a file is opened using open() function, it returns a
file object called a file handler that provides methods for
accessing the file.
• Open() takes two parameters  filename and mode
• Syntax:
file_handler_object = open(filename, mode)
example: fp = open(“hello.txt”, “r”)
file_handler = open("C:\prog\example.txt",“w")
• Example:
file_handler = open("C:\prog\example.txt","r")

file_handler = open("C:\\fauna\\bison.txt","r")

file_handler = open("C:\\network\computer.txt","r")

file_handler = open(r"C:\network\computer.txt","r“)
File modes
Modes Description
“r” Opens the file in read only mode and
this is the default mode.
“w” Opens the file for writing. If a file
already exists, then it’ll get
overwritten. If the file does not exist,
then it creates a new file.
“a” Opens the file for appending data at
the end of the file automatically. If
the file does not exist it creates a new
file.
“r+” Opens the file for both reading and
writing.
“w+” Opens the file for reading and writing.
If the file does not exist it creates a
new file. If a file already exists then it
will get overwritten.
Modes Description
“a+” Opens the file for reading and appending.
If a file already exists, the data is
appended. If the file does not exist it
creates a new file.
“x” Creates a new file. If the file already
exists, the operation fails.

“rb” Opens the binary file in read-only


mode.
“wb” Opens the file for writing the data in
binary format.
“rb+” Opens the file for both reading and
writing in binary format.
• If you do not explicitly close a file, Python’s garbage
collector will eventually destroy the object and close the
opened file for you, but the file stays open for a while.
• If an exception occurs while performing some operation on
the file, then the code exits without closing the file. In
order to overcome this problem, you should use a try-
except finally block to handle exceptions.
try:
fp = open("file", "w")
try:
fp.write('Hello World!')
finally:
fp.close()
except IOError:
print('oops error!')
#python code to open , read, print its contents and close a file
def read_file():
try:
file_handler = open("welcome.txt")
try:
print("Printing each line in the text file")
for each_line in file_handler:
print(each_line)
finally:
file_handler.close()
except IOError:
print("could not open the file")
def main():
read_file()
if __name__ == "__main__":
main()
Use of With statement to open and close a file

• We can use a with statement in Python so


that it is not necessary to close the file
handler object.
• Syntax:
with open (file, mode) as file_handler:
statement 1
statement 2 …
statement n
def read_file():
print("Printing each line in text file")
with open(“welcome.txt") as file_handler:
for each_line in file_handler:
print(each_line, end="")
def main():
read_file()
if __name__ == "__main__":
main()
• Using with to open more than one file
with open(in_filename) as in_file,
open(out_filename, 'w') as out_file:
for line in in_file:
------
------
out_file.write(parsed_line)
File object(file handler) attributes
File Attribute Description
file_handler.closed It returns a Boolean True if the
file is closed or False otherwise.

file_handler.mode It returns the access mode with


which the file was opened.

file_handler.name It returns the name of the file.


2. File methods to read data
3. File methods to write data
Method Syntax Description
read() file_handler. read([size]) read the contents of a file up to a
size and return it as a string

readline() file_handler.readline() read a single line in file.

readlines() file_handler.readlines() read all the lines of a file as list


items.
write() file_handler. write(string) write the contents of the string to
the file, returning the number of
characters written.
If you want to start a new line,
you must include the new line
character.
Method Syntax Description
writelines() file_handler. write a sequence of strings to the
writelines(sequence) file.

tell() file_handler.tell() returns an integer giving the file


handler’s current position within
the file, measured in bytes from
the beginning of the file.

seek() file_handler. seek(offset, used to change the file handler’s


from_what) position.
Offset  value which is added to
Example: reference point
fp.seek(3,1) From_what reference point
It says move 3 bytes selected ( 0 beginning of file
forward from current 1 current pos ,
position 2 end of file )
4. Closing a file

• It is important to close the file once the


processing is completed.
• Opening files consume system resources, and,
depending on the file mode, other programs
may not be able to access them.
• Syntax: file_handler.close()
• example : fp.close()
5. Delete or remove a file
• Python’s shutil module offers the remove()
method to delete files from the file system.
• Example code:
import shutil
import os
#two ways to delete file
shutil.os.remove('/python/progs/welcome.txt')
os.remove ('/python/progs/welcome.txt')
6. Seek() and 7. tell()
• The seek() method is used to set the file handler’s current position.
• Note: Reference point at current position / end of file cannot be
set in text mode except when offset is equal to 0.
• tell() methods prints the current position of file handler

f = open('workfile', 'w')
f.write('0123456789abcdef')
f.close()
f = open('workfile', 'r')
print("file contents are: ")
print(f.read())

f.seek(2)
print("reading data starting at 2 bytes from 0 position:",f.read())
print("current position of file handler is :")
print(f.tell())
f.close()
Object Oriented Programming
1. Classes and Objects;
2. Creating Classes and Objects;
3. Constructor Method;
4. Classes with Multiple Objects;
5. Objects as Arguments;
6. Objects as Return Values;
7. Encapsulation- Definition, Private Instance Variables;
8. Inheritance-
A. Single
B. Multiple Inheritance,
C. Multilevel
D. Multipath Inheritance;
9. Polymorphism- Definition, Operator Overloading.
Object-oriented programming (OOP)
• In Object-oriented programming (OOP) we use
objects to model real-world things that we want to
represent inside our programs and provide a simple
way to access their functionality.
• Advantages of Object-oriented programs are :
– easier to modify
– requires less work to maintain over time.
– code reuse,
– cleaner code,
– better architecture,
– abstraction layers,
– fewer programming bugs.
• Python supports encapsulation , inheritance and
polymorphism.
What is OOP ?
 easy explanation by Steve Jobs in an old
interview
• https://youtu.be/9CZFrneaASM
1. Classes and Objects
• A class is a blueprint from which individual
objects are created.
• An object is a instance of a class or it is a
bundle of related state (variables or data
members ) and behavior (methods or
functionality).
Generic object diagram
2. Creating classes and objects in
python
• Classes are defined by using the class keyword, followed by
the ClassName and a colon. Class definitions must be
executed before they have any effect.
• the statements inside a class definition will usually be
function definitions (methods of class)
• Syntax:
class classname:
<statement 1>
<statement 2>
--------------
<statement n>
Creating objects or Class instantiation in python:
• The syntax for object creation is,
object_name = ClassName(argument_1, argument_2, …..,
argument_n)
• The syntax to access data attribute is,
object_name . data_attribute_name

• The syntax to assign value to data attribute is,


object_name.date_attribute_name = value

• The syntax to call method attribute is,


object_name.method_attribute_name()
3. Constructor method __init__()
• Constructor method __init__() is a special method
that defines and initializes the instance variables. It is
invoked as soon as an object of a class is created or
instantiated.
• The __init__() method for a newly created object is
automatically executed with all of its parameters.
• The parameters for __init__() method are initialized
with the arguments that you had passed during
instantiation of the class object.
• Python allows you to define only one constructor per
class and it will be the first method definition of a class.
• syntax of a constructor or __init__()
def __init__(self, parameter_1, parameter_2, ….,
parameter_n) : statement(s)

• the self parameter in constructor and other methods:


– The first parameter in constructor definition or method
definition is the word self. When self is used, it is just a
variable name that points to the object that was created
and invoked this constructor or method.
– Also, Whenever we call a method using an object, the
object itself is automatically passed in as the first
parameter to the self parameter variable. The remaining
parameter variables must be supplied as arguments in the
calling method.
– It does not have to be named self , you can call it
whatever you like
Example – create class called mobile with two methods
and object called applemob

MOBILE

Methods

APPLEMOB Send_message()

Receive_message()
#class definition
class Mobile:
#constructor method
def __init__(self):
print("This message is from Constructor Method")
#method 1
def receive_message(self):
print("Receive message using Mobile")
#method 2
def send_message(self):
print("Send message using Mobile")

#main function
def main():
applemob = Mobile() #create an object called applemob
applemob.receive_message() # call the method
applemob.send_message() # call the method
if __name__ == "__main__":
main()
Example – create class called mobile with attribute mobile name
, two methods and object called applemob
MOBILE

DataAttributes

Mobile_name

Methods
APPLEMOB

Send_message()

Receive_message()
#class definition
class Mobile:
#constructor method
def __init__(self, name):
print(f"object is {self}")
self.mobile_name = name #assign name parameter to data attribute
#method1
def receive_message(self):
print(f"Receive message using {self.mobile_name} Mobile")
#method2
def send_message(self):
print(f"Send message using {self.mobile_name} Mobile")

#main function definiton


def main():
applemob = Mobile("apple iPhone12") #create object called applemob
applemob.receive_message() #call to method1
applemob.send_message() # call to method2
if __name__ == "__main__":
main()
Another example
class Person:
def __init__(self, name, age,course,sem):
self.name = name
self.age = age
self.course = course
self.sem = sem
def display(self):
print(" Student details")
print("Hello my name is " + self.name)
print(f"my age is {self.age}")
print("I study in " + self.course)
print(f"I study in {self.sem} semester")
#main function definiton
def main():
p1 = Person("samarth", 20,"bca",4)
p1.display()
if __name__ == "__main__":
main()
Delete attributes and objects

• to delete attributes and object itself we use


the DEL keyword or command
• example: delete a attribute age
p1 = Person("John", 36)
del p1.age
• example : delete the object p1
p1 = Person("John", 36)
del p1
4. Classes with Multiple Objects
• Multiple objects for a class can be created while attaching a unique copy
of data attributes and methods of the class to each of these objects.
class Birds:
def __init__(self, bird_name):
self.bird_name = bird_name
def flying_birds(self):
print(f"{self.bird_name} flies above clouds")
def non_flying_birds(self):
print(f"{self.bird_name} is the national bird of Australia")

def main():
vulture = Birds("Griffon Vulture") #object 1
emu = Birds("Emu") #object2
vulture.flying_birds() #object 1 method 1
emu.non_flying_birds() #object 2 method 2
if __name__ == "__main__":
main()
5. Objects as Arguments
• An object can be passed to a calling function (defined outside class )
as an argument.
#objects as argument to a function
class Track:
def __init__(self, song, artist):
self.song = song
self.artist = artist

#function defined outside class


def pinfo(vocalist):
print(f"Song is {vocalist.song}")
print(f"Artist is {vocalist.artist}")

singer = Track("Photograph","ed sheeran")


pinfo(singer)
6. Objects as return values
• Python can also return objects from methods.
• Example: return object R of class TwoNum
def Add(self, T):
R=TwoNum()
R.__x = self.__x + T.__x
R.__y = self.__y + T.__y
return R

• The id() function is used to find the identity of the location of the
object in memory.
syntax for id() function is,
id(object)
• Also we check whether an object is an instance of a given class or
not.
Syntax : isinstance (object, classinfo)
• Everything in python, almost everything is an object.
Lists, dictionaries, tuples are also python objects.
• The code below shows a python function that
returns a python dictionary.
# This function returns a dictionary
def foo():
d = dict();
d['str'] = “welcome"
d['x'] = 50
return d
print foo()
7. Encapsulation
• Encapsulation is the process of combining
variables that store data and methods that work
on these variables into a single unit called class.
• Encapsulation ensures that the object’s internal
representation (its state and behavior) are hidden
from the rest of the application thus promoting
data hiding.
• The variables are not accessed directly; it is
accessed through the methods present in the
class.
• Abstraction is a process which shows only
“relevant” variables that are used to access data
and “hide” implementation details of an object
from the user.
• An application using a class does not need to
know its internal workings or how it is
implemented. The program simply creates an
object and uses it to invoke the methods of that
class.
• Encapsulation promotes data hiding
• Abstraction promotes implementation hiding
Using private instance variables and methods
and Name Mangling
• Instance variables or methods, which can be accessed within the
same class and can’t be seen outside, are called private instance
variables or private methods.

• Name mangling:
– In Python, mangling is used for class attributes that one does not
want subclasses to use
– Name mangling is the encoding of function and variable names into
unique names so that linkers can separate common names in the
language.
– On encountering a mangled variable , python will replace it with one
trailing underscore and two leading underscores
__ClassName__Identifier
– It allows different entities to be named with the same identifier as
long as they occupy a different namespace or have
different signatures
#example on name mangling
class myClass:
def __init__(self):
self.x=10
self.__y=20

obj=myClass()
print(obj.x) #shows value 10
print(obj.__y) #shows error because it is a mangled variable
8. Inheritance
• Inheritance enables new classes to receive or
inherit variables and methods of existing classes.
• Thus the new class extends the features of
existing class by adding some new functionality.
• A class that is used as the basis for inheritance is
called a superclass or base class.
• A class that inherits from a base class is called a
subclass or derived class.
• Inheritance easily enables reusing of existing
code.
• Relationship between base class and derived class is
represented using is-a relationship .
• example: lemon is-a citrus fruit, which is-a fruit
• Syntax to define derived class
class DerivedClassName(BaseClassName):
<statement 1>
----------------
<statement n>
• example:
class fruit:
print(“this is base class fruit”)
class citrusfruit(fruit):
print(“this is derived class citrus fruit “)

• When the derived class object is constructed, the base


class is also remembered. If a requested attribute is not
found in the derived class, the search proceeds to look in
the base class.
Types of Inheritance
A) Single inheritance
• Single inheritance enables a derived class to inherit
variables and methods from a single base class. This
includes __init__() method.
• So, if you do not define __init__() in a derived class,
you will get the one from the base class.

• Note: refer program inherit_single.py
#single inheritance
#base class
class FootBall:
def __init__(self, country, division, no_of_times):
self.country = country
self.division = division
self.no_of_times = no_of_times
def fifa(self):
print(f"{self.country} national football team is placed in '{self.division}' FIFA division")

#derived class
class WorldChampions(FootBall):
def world_championship(self):
print(f"{self.country} national football team is {self.no_of_times} times world champions")

def main():
germany = WorldChampions("Germany", "UEFA", 4)
germany.fifa()
germany.world_championship()
if __name__ == "__main__":
main()
Super() function
• The super() function is used to give access to
methods and properties of a parent or sibling
class. Hence a method from parent class can be
called using a super()
• The super() function returns an object that
represents the parent class.
• syntax:
super().__init__(base_class_parameter(s))

• Note: for program refer inherit super.py


#super method
#base class Emp
class Emp():
def __init__(self, id, name, address):
self.id = id
self.name = name
self.address = address

# derived class freelancer inherits EMP


class Freelance(Emp):
def __init__(self, id, name, address, Emails):
super().__init__(id, name, address)
self.Emails = Emails

Emp_1 = Freelance(103, "rohan patil", "belgaum" , "[email protected]")


print('The ID is:', Emp_1.id) #base class parameter
print('The Name is:', Emp_1.name) #base class parameter
print('The Address is:', Emp_1.address) #base class parameter
print('The Emails is:', Emp_1.Emails) #derived class parameter
Method Overriding

• Method overriding allows a derived class to


provide its own implementation of a method that
is already provided in base class.
• Derived classes override methods of their base
class when they want to use some behaviours of
base class but not all of them.
• These methods have the same name and
signature as those in the base class.
• Method overriding is mostly useful in multiple
inheritance
• Note: for program refer inherit overriding.py
#method overriding
class Book:
def __init__(self, author, title):
self.author = author
self.title = title
def book_info(self): #base class method
print(f"{self.title} is authored by {self.author}")

class Fiction(Book):
def __init__(self, author, title, publisher):
super().__init__(author, title)
self.publisher = publisher
def book_info(self): #derived class method
print(f"{self.title} is authored by {self.author} and published by
{self.publisher}")
def invoke_base_class_method(self):
super().book_info() # calls base class method
#main function continued
def main():
print("Derived Class")
book1 = Fiction("RK narayan", "Swami and friends", "Mysore
publications")
book1.book_info() #calls derived class bookinfo with book1 obj

book1.invoke_base_class_method() #calls base class bookinfo with


book1
print("---------------------------------")
print("Base Class")
book2 = Book("Dr APJ Abdul Kalam", "Wings of Fire")
book2.book_info() #calls base class bookinfo with book2
if __name__ == "__main__":
main()
#hierarchical inheritance with method overriding
class Bank:
def getroi(self):
Bank
return 10;
class SBI(Bank):
def getroi(self): ICICI
SBI
return 7;

class ICICI(Bank):
def getroi(self):
return 8;
b1 = Bank()
b2 = SBI()
b3 = ICICI()
print("Bank Rate of interest:",b1.getroi());
print("SBI Rate of interest:",b2.getroi());
print("ICICI Rate of interest:",b3.getroi());
B) Multiple inheritance

• In multiple inheritance , a derived class inherits


properties from multiple base classes syntax:
class DerivedClassName(Base_1, Base_2, Base_3):
<statement 1>
...
<statement n>
• The base class methods can be called directly
baseclassname.method(self, arguments)
#Example 1- multiple inheritance
class Calculation1:
def Summation(self,a,b):
Calculation1 Calculation2
return a+b;
class Calculation2:
def Multiplication(self,a,b): Derived
return a*b;
class Derived(Calculation1,Calculation2):
def Divide(self,a,b):
return a/b;
def main():
d = Derived()
print("Sum is=",d.Summation(1,2))
print("Product is=",d.Multiplication(1,2))
print("division is=",d.Divide(1,2))
if __name__=="__main__":
main()
Example 2 multiple inheritance

Theory Practical

FinalGrade

Refer program : inherit multiple.py


class Theory:
def __init__(self, theory_marks):
self.theory_marks = theory_marks
def display_theory_marks(self):
print(f" Theory marks are {self.theory_marks}")
class Practical:
def __init__(self, practical_marks):
self.practical_marks = practical_marks
def display_practical_marks(self):
print(f" Practical marks are {self.practical_marks}")
class FinalGrade(Theory, Practical):
def __init__(self, theory_marks, practical_marks):
Theory.__init__(self, theory_marks)
Practical.__init__(self, practical_marks)
self.Total_marks=self.theory_marks+self.practical_marks
def displaytotalscore(self):
Theory.display_theory_marks(self)
Practical.display_practical_marks(self)
print(" Total Score is =",self.Total_marks)
def main():
print(f"Is FinalGrade a derived class of Theory Class")
print(issubclass(FinalGrade,(Theory, Practical)))
result = FinalGrade(80,90)
result.displaytotalscore()
if __name__ == "__main__":
main()
Method resolution order:
(MRO)
• In the case of multiple inheritance, a given attribute is first searched
in the current class, if it’s not found then it’s searched in the parent
classes. The parent classes are searched in a left-right fashion and
each class is searched once.

• The order that is followed is known as a linearization of the class


Derived and this order is found out using a set of rules called
Method Resolution Order (MRO).

• To view the MRO of a class:

– Use the mro() method, it returns a list


Eg. Class4.mro()

– Use the _mro_ attribute, it returns a tuple


Eg. Class4.__mro__
# Python program to demonstrate super() and mro
class Class1:
def m(self):
print("In Class1")
class Class2(Class1):
def m(self):
print("In Class2")
super().m()
class Class3(Class1):
def m(self):
print("In Class3")
super().m()
class Class4(Class2, Class3):
def m(self):
print("In Class4")
super().m()

print(Class4.mro()) #This will print list


print(Class4.__mro__) #This will print tuple
Output of program on super and mro

[<class '__main__.Class4'>, <class '__main__.Class2'>,


<class '__main__.Class3'>, <class '__main__.Class1'>,
<class 'object'>]
In Class4
In Class2
In Class3
In Class1
None
(<class '__main__.Class4'>, <class '__main__.Class2'>,
<class '__main__.Class3'>, <class '__main__.Class1'>,
<class 'object'>)
C) Multilevel inheritance
• The inheritance of a derived class from another
derived class is called as multilevel inheritance in
Python.
• This is possible to any level of depth.
• Example:
Class Base
<statements>
Class Derived1(Base):
<statements>
Class Derived2(Derived1):
<statements>
Multilevel example

EMPLOYEE

SALARY

DESIGNATION
#multilevel inheritance
class Employees():
def display_Name(self):
print("Employee Name: Khush")

class Salary(Employees):
def display_Sal(self):
print("Salary: 10000")

class Designation(Salary):
def display_desig(self):
Employees.display_Name(self)
Salary.display_Sal(self)
print("Designation: Test Engineer")

emp = Designation() # create object of designation class


emp.display_desig() #call method
D) Multipath inheritance
(Diamond problem)
• A derived class with two base classes and these two base
classes have one common base class is called multipath
inheritance or diamond problem.
• Ambiguity can arise in this type of inheritance.
• In multipath inheritance , the derived class Z
will inherit the properties of base class A from
two paths ( from X and from Y). Hence there
will be duplicates copies of A in Z.
• To resolve this , we make use of super()
method. It will invoke all the methods directly
from the subclass without any duplication.
• However , the MRO is followed while
choosing the overridden functions.
#multipath inheritance
class A:
def target(self):
print("Invoked method in class A")
Output
class B(A): Invoked method in class D
def target(self): Invoked method in class B
print("Invoked method in class B") Invoked method in class C
super().target() Invoked method in class A

class C(A):
def target(self):
print("Invoked method in class C")
super().target()

class D(B, C):


def target(self):
print("Invoked method in class D")
super().target()
obj = D()
obj.target()
9. Polymorphism

• The word "polymorphism" means "many


forms", and in programming it refers to
methods/ functions/operators with the same
name that can be executed on many objects
or classes.
• i.e. we can have common methods in a base
class and implement them differently in other
derived classes.
class Vehicle:
def __init__(self, brand, model):
self.brand = brand
self.model = model
Output
def move(self):
Ford
print("Move!")
Mustang
class Car(Vehicle): Move!
pass Ibiza
Touring 20
class Boat(Vehicle):
def move(self):
Sail!
print("Sail!") Boeing
747
class Plane(Vehicle):
Fly!
def move(self):
print("Fly!")

car1 = Car("Ford", "Mustang") #Create a Car object


boat1 = Boat("Ibiza", "Touring 20") #Create a Boat object
plane1 = Plane("Boeing", "747") #Create a Plane object

for x in (car1, boat1, plane1):


print(x.brand)
print(x.model)
x.move()
Operator Overloading

• Operator Overloading is a specific case of


polymorphism, where different operators have
different implementations depending on their
arguments.
• Operator overloading gives extended meaning to
the predefined task of the operator.
• 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.
• To perform operator overloading, Python
provides some special function or magic
function that is automatically invoked when it
is associated with that particular operator.
• These magic methods start with double
underscores and end with double
underscores.
• For example, when we use + operator, the
magic method __add__ is automatically
invoked in which the operation for + operator
is defined.
#adding two complex objects using operator overloading
class Complex:
def __init__(self, real, imaginary):
self.real = real
self.imaginary = imaginary
def __add__(self, other):
return Complex(self.real + other.real, self.imaginary + other.imaginary)
def __str__(self):
return f"{self.real} + i{self.imaginary}"
def main():
complex_number_1 = Complex(4, 5)
complex_number_2 = Complex(2, 3)
complex_number_sum = complex_number_1 + complex_number_2
print(f"Addition of two complex numbers {complex_number_1} and
{complex_number_2} is {complex_number_sum}")
if __name__ == "__main__":
main()

Output: Addition of two complex numbers 4 + i5


and 2 + i3 is 6 + i8
#comparing two rectangle objects using operator overloading
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def __gt__(self, other):
rectangle_1_area = self.width * self.height
rectangle_2_area = other.width * other.height
return rectangle_1_area > rectangle_2_area
def main():
rectangle_1_obj = Rectangle(5, 10)
rectangle_2_obj = Rectangle(3, 4)
if rectangle_1_obj > rectangle_2_obj:
print("Rectangle 1 is greater than Rectangle 2")
else:
print("Rectangle 2 is greater than Rectangle 1")
if __name__ == "__main__":
main()
Output:
Rectangle 1 is greater than Rectangle 2

You might also like