0% found this document useful (0 votes)
17 views232 pages

Advanced Python Material-converted

The document provides an introduction to Object-Oriented Programming (OOP) in Python, focusing on the concept of classes, objects, and various types of variables and methods. It explains how to define a class, create objects, and the role of constructors, instance variables, static variables, and methods. Additionally, it includes examples and comparisons between methods and constructors, as well as how to access and delete instance variables.

Uploaded by

sruthisadhu29
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)
17 views232 pages

Advanced Python Material-converted

The document provides an introduction to Object-Oriented Programming (OOP) in Python, focusing on the concept of classes, objects, and various types of variables and methods. It explains how to define a class, create objects, and the role of constructors, instance variables, static variables, and methods. Additionally, it includes examples and comparisons between methods and constructors, as well as how to access and delete instance variables.

Uploaded by

sruthisadhu29
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/ 232

1

OOP’s
Part - 1

KESA PAVAN KUMAR Cell No: 9848461833


2

What is Class:
⚽ In Python every thing is an object. To create objects we required some
Model or Plan or Blue print, which is nothing but class.
⚽ We can write a class to represent properties (attributes) and actions
(behaviour) of object.

⚽ Properties can be represented by variables


⚽ Actions can be represented by Methods.

⚽ Hence class contains both variables and methods.

How to define a Class?


We can define a class by using class keyword.

Syntax:
class className:
''' documenttation string '''
variables:instance variables,static and local
variables methods: instance methods,static
methods,class methods

Documentation string represents description of the class. Within the class


doc string is always optional. We can get doc string by using the following 2
ways.

1) print(classname. doc )
2) help(classname)

Example:
1) class Student:
2) ''''' This is student class with required data'''
3) print(Student. doc )
4) help(Student)

Within the Python class we can represent data by using

variables. There are 3 types of variables are allowed.

1) Instance Variables (Object Level Variables)


2) Static Variables (Class Level Variables)
3) Local variables (Method Level Variables)

KESA PAVAN KUMAR Cell No: 9848461833


3

Within the Python class, we can represent operations by using methods. The
following are various types of allowed methods

1) Instance Methods
2) Class Methods
3) Static Methods

Example for Class:

1) class Student:
2) '''''Developed by durga for python demo'''
3) def init (self):
4) self.name='dur
5) ga'
self.age=
6) 40
self.marks=
7) 80
8) def talk(self):
9) print("Hello I am
10 :",self.name)
print("My Age
)11 is:",self.age)
print("My Marks
) are:",self.marks)
What is Object:
Pysical existence of a class is nothing but object. We can create any number
of objects for a class.

Syntax to Create Object: referencevariable = classname()

Example: s = Student()

What is Reference Variable?


The variable which can be used to refer object is called reference
variable. By using reference variable, we can access properties
and methods of object.

Program: Write a Python program to create a Student class and Creates an


object to it. Call the method talk() to display student details

1) class Student:
2)
3) def init
(self,name,rollno,marks):
4) self.name=na
5) me
self.rollno=roll
6) no
self.marks=mar
7) ks

KESA PAVAN KUMAR Cell No: 9848461833


4

8) def talk(self):
9) print("Hello My Name is:",self.name)
10) print("My Rollno is:",self.rollno)
11) print("My Marks are:",self.marks)
12)
13) s1=Student("Durga",101,80)
14) s1.talk()

Output:
D:\durgaclasses>py
test.py Hello My Name
is: Durga My Rollno is:
101
My Marks are: 80

Self Variable:
 self is the default variable which is always pointing to current object (like
this keyword in Java)
 By using self we can access instance variables and instance methods of object.

Note:
1) self should be first parameter inside
constructor def init (self):
2) self should be first parameter inside instance
methods def talk(self):

Constructor Concept:
☕ Constructor is a special method in python.
☕ The name of the constructor should be init (self)
☕ Constructor will be executed automatically at the time of object creation.
☕ The main purpose of constructor is to declare and initialize instance variables.
☕ Per object constructor will be exeucted only once.
☕ Constructor can take atleast one argument(atleast self)
☕ Constructor is optional and if we are not providing any constructor then
python will provide default constructor.

Example:
1) def init (self,name,rollno,marks):
2) self.name=name
3) self.rollno=rollno
4) self.marks=marks

KESA PAVAN KUMAR Cell No: 9848461833


5

Program to demonstrate Constructor will execute only once per Object:


1) class Test:
2)
3) def init (self):
4) print("Constructor exeuction...")
5)
6) def m1(self):
7) print("Method execution...")
8)
9) t1=Test()
10) t2=Test()
11) t3=Test()
12) t1.m1()

Output
Constructor
exeuction...
Constructor
exeuction...
Constructor
exeuction... Method
execution...

Program:

1) class
Student:
2)
3) ''''' This is student class with required data'''
4) def init (self,x,y,z):
5) self.name
6) =x
self.rollno
7) =y
self.marks
8) =z
9) def display(self):
10) print("Student Name:{}\nRollno:{}
\nMarks:{}".format(self.name,self.rollno,self
11).marks))
12) s1=Student("Durga",101,80)
13) s1.display()
14) s2=Student("Sunny",102,100)
15)
s2.display()
Output
Student
Name:Durga
Rollno:101
Marks:80
KESA PAVAN KUMAR Cell No: 9848461833
6

Student
Name:Sunny
Rollno:102
Marks:100

Differences between Methods and Constructors


Method Construct
or
1) Name of method can be any name 1) Constructor name should be always
init
2) Method will be executed if we call that 2) Constructor will be executed
method automatically at
the time of object creation.
3) Per object, method can be called any 3) Per object, Constructor will be executed
number only
of times. once
4) Inside method we can write business 4) Inside Constructor we have to declare
logic and
initialize instance variables

Types of Variables:
Inside Python class 3 types of variables are allowed.

1) Instance Variables (Object Level Variables)


2) Static Variables (Class Level Variables)
3) Local variables (Method Level Variables)

1)Instance Variables:
 If the value of a variable is varied from object to object, then such type of
variables are called instance variables.
 For every object a separate copy of instance variables will be created.

Where we can declare Instance Variables:


1) Inside Constructor by using self variable
2) Inside Instance Method by using self variable
3) Outside of the class by using object reference variable

1) Inside Constructor by using Self Variable:


We can declare instance variables inside a constructor by using self
keyword. Once we creates object, automatically these variables will be
added to the object.

1) class Employee:
2)
3) def init (self):
KESA PAVAN KUMAR Cell No: 9848461833
4) self.eno=1
5) 00
self.ename='Dur
7

6) self.esal=10000
7)
8) e=Employee()
9) print(e. dict )

Output: {'eno': 100, 'ename': 'Durga', 'esal': 10000}

2) Inside Instance Method by using Self Variable:


We can also declare instance variables inside instance method by using
self variable. If any instance variable declared inside instance method, that
instance variable will be added once we call taht method.

1) class Test:
2)
3) def init (self):
4) self.a=10
5) self.b=20
6)
7) def m1(self):
8) self.c=30
9)
10) t=Test()
11) t.m1()
12) print(t. dict )

Output: {'a': 10, 'b': 20, 'c': 30}

3) Outside of the Class by using Object Reference


Variable:
We can also add instance variables outside of a class to a particular object.

1) class
Test:
2)
3) def init (self):
4) self.a=1
5) 0
6) self.b=2
def m1(self):
7) 0
self.c=3
8) 0
9) t=Test()
10) t.m1()
11) t.d=40
12) print(t. dict )

Output {'a': 10, 'b': 20, 'c': 30, 'd': 40}

KESA PAVAN KUMAR Cell No: 9848461833


8

How to Access Instance Variables:


We can access instance variables with in the class by using self variable and
outside of the class by using object reference.

1) class Test:
2)
3) def init (self):
4) self.a=1
5) self.b=20
0
6) def display(self):
7) print(self.a)
8) print(self.b)
9)
10) t=Test()
11)
12) t.display()
print(t.a,t.b)

Outpu
t 10
20
10 20

How to delete Instance Variable from the Object:


1) Within a class we can delete instance variable as
follows del self.variableName

2) From outside of class we can delete instance variables


as follows del objectreference.variableName

1) class
Test:def init (self):
2)
3) self.a=1
4) 0
self.b=2
5) 0
self.c=3
6) 0
self.d=4
7) 0 m1(self):
def
8) del
9) self.d
10) t=Test()
11) print(t. dict
)12) t.m1()

13)
14) print(t.
del t.c dict
)

15) print(t. dict


)

KESA PAVAN KUMAR Cell No: 9848461833


9

Output
{'a': 10, 'b': 20, 'c': 30, 'd': 40}
{'a': 10, 'b': 20, 'c': 30}
{'a': 10, 'b': 20}

Note: The instance variables which are deleted from one object, will not be
deleted from other objects.

1) class
Test:
2) def init (self):
3) self.a=1
4) 0
self.b=2
5) 0
self.c=3
6) 0
7) self.d=4
0
8) t1=Test()
9) t2=Test()
10) del t1.a
11) print(t1. dict )
12) print(t2. dict )

Output
{'b': 20, 'c': 30, 'd': 40}
{'a': 10, 'b': 20, 'c': 30, 'd': 40}

If we change the values of instance variables of one object then those


changes won't be reflected to the remaining objects, because for every object
we are separate copy of instance variables are available.

1) class
Test:def init (self):
2)
3) self.a=1
4) 0
self.b=2
5) 0
6) t1=Test()
7) t1.a=888
8) t1.b=999
9) t2=Test()
10) print('t1:',t1.a,t1.b)
11)
print('t2:',t2.a,t2.b)
Output
t1: 888 999
t2: 10 20

KESA PAVAN KUMAR Cell No: 9848461833


10

2)Static Variables:
☕ If the value of a variable is not varied from object to object, such type of
variables we have to declare with in the class directly but outside of
methods. Such types of variables are called Static variables.
☕ For total class only one copy of static variable will be created and shared
by all objects of that class.
☕ We can access static variables either by class name or by object reference.
But recommended to use class name.

Instance Variable vs Static Variable:


Note: In the case of instance variables for every object a separate copy will
be created, but in the case of static variables for total class only one copy will
be created and shared by every object of that class.

1) class Test:
2) x=10
3) def init
4) self.y=2
(self): 5)
0
6) t1=Test()
7) t2=Test()
8) print('t1:',t1.x,t1.y)
9) print('t2:',t2.x,t2.y)
10) Test.x=888
11) t1.y=999
12)
13) print('t1:',t1.x,t1.y)
print('t2:',t2.x,t2.y)

Output
t1: 10 20
t2: 10 20
t1: 888 999
t2: 888 20

Various Places to declare Static Variables:


1) In general we can declare within the class directly but from outside of any method
2) Inside constructor by using class name
3) Inside instance method by using class name
4) Inside classmethod by using either class name or class variable
5) Inside static method by using class name

KESA PAVAN KUMAR Cell No: 9848461833


11

1) class Test:
2) a=10
3) def init (self):
4) Test.b=20
5) def m1(self):
6) Test.c=30
7) @classmethod
8) def m2(cls):
9) cls.d1=40
10) Test.d2=400
11) @staticmethod
12) def m3():
13) Test.e=50
14) print(Test. dict )
15) t=Test()
16) print(Test. dict )
17) t.m1()
18) print(Test. dict )
19) Test.m2()
20) print(Test. dict )
21) Test.m3()
22) print(Test. dict )
23) Test.f=60
24) print(Test. dict )

How to access Static Variables:


1) inside constructor: by using either self or classname
2) inside instance method: by using either self or classname
3) inside class method: by using either cls variable or classname
4) inside static method: by using classname
5) From outside of class: by using either object reference or classname

1) class Test:
2) a=10
3) def init (self):
4) print(self.a)
5) print(Test.a)
6) def m1(self):
7) print(self.a)
8) print(Test.a)
9) @classmethod
10) def m2(cls):
11) print(cls.a)
12) print(Test.a)

KESA PAVAN KUMAR Cell No: 9848461833


12

13) @staticmethod
14) def m3():
15) print(Test.a)
16) t=Test()
17) print(Test.a)
18) print(t.a)
19) t.m1()
20) t.m2()
21) t.m3()

Where we can modify the Value of Static Variable:


Anywhere either with in the class or outside of class we can modify by using
classname. But inside class method, by using cls variable.

1) class Test:
2) a=777
3)
4) @classmeth
def m1(cls):
od
5) cls.a=88
6) 8
@staticmethod
7) def m2():
8) Test.a=99
9) 9
print(Test.a)
10) Test.m1()

11)
12) Test.m2()
print(Test.a)

13)
Outpu
print(Test.a)
t 777
888
999

*****
If we change the Value of Static Variable by using
either self OR Object Reference Variable:
If we change the value of static variable by using either self or object
reference variable, then the value of static variable won't be changed, just a
new instance variable with that name will be added to that particular object.

1) class Test:
2) a=10
3) def m1(self):
4) self.a=888

KESA PAVAN KUMAR Cell No: 9848461833


13

5) t1=Test()
6) t1.m1()
7) print(Test.a)
8) print(t1.a)

Outpu
t 10
888

1) class Test:
2) x=10
3) def init
4) self.y=2
(self): 5)
0
6) t1=Test()
7) t2=Test()
8) print('t1:',t1.x,t1.y)
9) print('t2:',t2.x,t2.y)
10) t1.x=888
11) t1.y=999
12)
13) print('t1:',t1.x,t1.y)
print('t2:',t2.x,t2.y)

Output
t1: 10
20
t2: 10 20
t1: 888 999
t2: 10 20

1) class Test:
2) a=10
3) def init (self):
4) self.b=20
5) t1=Test()
6) t2=Test()
7) Test.a=888
8) t1.b=999
9) print(t1.a,t1.b)
10) print(t2.a,t2.b)

Output
888 999
888 20

KESA PAVAN KUMAR Cell No: 9848461833


14

1) class Test:
2) a=10
3) def init (self):
4) self.b=2
5) def
0 m1(self):
6) self.a=88
7) 8
self.b=99
8) 9
9)
t1=Test()
10) t2=Test()

11)
12) t1.m1()
print(t1.a,t1.b)
13) print(t2.a,t2.
b)
Output
888
999
10 20

1) class Test:
2) a=10
3) def init (self):
4) self.b=2
5) @classmethod
0
6) def m1(cls):
7) cls.a=88
8) 8
cls.b=9
9) 99
10) t1=Test()
11) t2=Test()
12) t1.m1()
13) print(t1.a,t1.b)
14) print(t2.a,t2.b)
15)
print(Test.a,Test.b)
Outpu
t 888
20
888 20
888 999

KESA PAVAN KUMAR Cell No: 9848461833


15

How to Delete Static Variables of a Class:


1) We can delete static variables from anywhere by using the
following syntax del classname.variablename

2) But inside classmethod we can also use cls


variable del cls.variablename

1) class Test:
2) a=10
3) @classmethod
4) def m1(cls):
5) del cls.a
6) Test.m1()
7) print(Test. dict )

Example:

1) class Test:
2) a=10
3) def init (self):
4) Test.b=2
5) 0
del
6) Test.a
def m1(self):
7) Test.c=3
8) 0
del
9) Test.b
10) def @classmeth
m2(cls):
od
11 cls.d=4
)12 0
del
)13) Test.c
14) def @staticmeth
m3():
od
15 Test.e=5
)16 0
del
)17) print(Test.
Test.d dict
)18) t=Test()

19)
20) print(Test.
t.m1() dict
)
22) Test.m2()
21) print(Test. dict
)
24) Test.m3()
23) print(Test. dict
26)
) Test.f=60

25) print(Test. dict


)

27) print(Test. dict


KESA PAVAN KUMAR Cell No: 9848461833
)
16

28) del Test.e


29) print(Test. dict )

****Note:
⚽ By using object reference variable/self we can read static variables, but
we cannot modify or delete.
⚽ If we are trying to modify, then a new instance variable will be added to
that particular object.
⚽ t1.a = 70
⚽ If we are trying to delete then we will get error.

Example:
1) class Test:
2) a=10
3)
4) t1=Test()
5) del t1.a ===>AttributeError: a

We can modify or delete static variables only by using classname or cls variable.

1) import sys
2) class Customer:
3) ''''' Customer class with bank
operations..
4) '''
bankname='DURGABANK'

5)
6) def init (self,name,balance=0.0):
self.name=na
7) me
self.balance=bala
8) defnce
deposit(self,amt):
9) self.balance=self.balance+
10 amt
print('Balance after
)11) def deposit:',self.balance)
withdraw(self,amt):
12 if
)13 amt>self.balance
print('Insufficient Funds..cannot perform this
)
14 : sys.exit
operation')
)15 ()
self.balance=self.balance-
)16 amt
print('Balance after
)17) withdraw:',self.balance)
18) print('Welcome to',Customer.bankname)
19) name=input('Enter Your Name:')
20) c=Customer(name)
21) while True:
22) print('d-Deposit \nw-Withdraw \ne-exit')
23) option=input('Choose your
option:')

KESA PAVAN KUMAR Cell No: 9848461833


17

24) if option=='d' or option=='D':


25) amt=float(input('Enter amount:'))
26) c.deposit(amt)
27) elif option=='w' or option=='W':
28) amt=float(input('Enter amount:'))
29) c.withdraw(amt)
30) elif option=='e' or option=='E':
31) print('Thanks for Banking')
32) sys.exit()
33) else:
34) print('Invalid option..Plz choose valid option')

Output:
D:\durga_classes>py
test.py Welcome to
DURGABANK Enter
Your Name:Durga
d-Deposit
w-
Withdraw
e-exit

Choose your
option:d Enter
amount:10000
Balance after deposit:
10000.0 d-Deposit
w-
Withdraw
e-exit

Choose your
option:d Enter
amount:20000
Balance after deposit:
30000.0 d-Deposit
w-
Withdraw
e-exit

Choose your
option:w Enter
amount:2000
Balance after withdraw:
28000.0 d-Deposit
w-
Withdraw
e-exit

Choose your option:r


KESA PAVAN KUMAR Cell No: 9848461833
18

Invalid option..Plz choose valid


option d-Deposit
w-Withdraw

KESA PAVAN KUMAR Cell No: 9848461833


19

e-exit

Choose your
option:e Thanks
for Banking

3)Local Variables:
⚽ Sometimes to meet temporary requirements of programmer,we can declare
variables inside a method directly,such type of variables are called local
variable or temporary variables.
⚽ Local variables will be created at the time of method execution and
destroyed once method completes.
⚽ Local variables of a method cannot be accessed from outside of method.

1) class Test:
2) def m1(self):
3) a=1000
4) print(a)
5) def m2(self):
6) b=2000
7) print(b)
8) t=Test()
9) t.m1()
10) t.m2()

Outpu
t 1000
2000

1) class
Test:
2) def m1(self):
3) a=100
4) 0
print(a
5) )
def
m2(self):
6) b=200
7) 0
print(a) #NameError: name 'a' is not
8) defined
print(b
9) )
t=Test()
10) t.m1()

11) t.m2()

KESA PAVAN KUMAR Cell No: 9848461833


20

Types of Methods:
Inside Python class 3 types of methods are allowed

1) Instance Methods
2) Class Methods
3) Static Methods

1)Instance Methods:
⚽ Inside method implementation if we are using instance variables then such
type of methods are called instance methods.
⚽ Inside instance method declaration, we have to pass self variable. def m1(self):
⚽ By using self variable inside method we can able to access instance variables.
⚽ Within the class we can call instance method by using self variable and from
outside of the class we can call by using object reference.

1) class Student:
2) def init (self,name,marks):
3) self.name=name
4) self.marks=marks
5) def display(self):
6) print('Hi',self.name)
7) print('Your Marks are:',self.marks)
8) def grade(self):
9) if self.marks>=60:
10) print('You got First Grade')
11) elif self.marks>=50:
12) print('Yout got Second Grade')
13) elif self.marks>=35:
14) print('You got Third Grade')
15) else:
16) print('You are Failed')
17) n=int(input('Enter number of students:'))
18) for i in range(n):
19) name=input('Enter Name:')
20) marks=int(input('Enter Marks:'))
21) s= Student(name,marks)
22) s.display()
23) s.grade()
24) print()

Ouput:
D:\durga_classes>py
test.py Enter number of
students:2

KESA PAVAN KUMAR Cell No: 9848461833


21

Enter
Name:Durga
Enter Marks:90
Hi Durga
Your Marks are:
90 You got First
Grade

Enter
Name:Ravi
Enter
Marks:12 Hi
Ravi
Your Marks are:
12 You are
Failed

Setter and Getter Methods:


We can set and get the values of instance variables by using getter and setter methods.

Setter Method:
setter methods can be used to set values to the instance variables. setter
methods also known as mutator methods.

Syntax:
def
setVariable(self,variab
le):
self.variable=variable

Example:
def
setName(self,name)
: self.name=name

Getter Method:
Getter methods can be used to get values of the instance variables. Getter
methods also known as accessor methods.

Syntax:
def
getVariable(self)
: return
self.variable

Example:
def
getName(self):
return
KESA PAVAN KUMAR Cell No: 9848461833
22

self.name

1) class Student:
2) def setName(self,name):
3) self.name=name
4)

KESA PAVAN KUMAR Cell No: 9848461833


23

5) def getName(self):
6) return self.name
7)
8) def setMarks(self,marks):
9) self.marks=marks
10)
11) def getMarks(self):
12) return self.marks
13)
14) n=int(input('Enter number of students:'))
15) for i in range(n):
16) s=Student()
17) name=input('Enter Name:')
18) s.setName(name)
19) marks=int(input('Enter Marks:'))
20) s.setMarks(marks)
21)
22) print('Hi',s.getName())
23) print('Your Marks are:',s.getMarks())
24) print()

Output:
D:\python_classes>py
test.py Enter number of
students:2

Enter
Name:Durga
Enter Marks:100
Hi Durga
Your Marks are: 100

Enter
Name:Ravi
Enter
Marks:80 Hi
Ravi
Your Marks are: 80

2)Class Methods:
⚽ Inside method implementation if we are using only class variables (static
variables), then such type of methods we should declare as class method.
⚽ We can declare class method explicitly by using @classmethod decorator.
⚽ For class method we should provide cls variable at the time of declaration
⚽ We can call classmethod by using classname or object reference variable.

KESA PAVAN KUMAR Cell No: 9848461833


24

1) class Animal:
2) lEgs=4
3) @classmethod
4) def walk(cls,name):
5) print('{} walks with {} lEgs...'.format(name,cls.lEgs))
6) Animal.walk('Dog')
7) Animal.walk('Cat')

Output
D:\python_classes>py
test.py Dog walks with 4
lEgs...
Cat walks with 4 lEgs...

Program to track the Number of Objects created for a Class:


1) class Test:
2) count=0
3) def init (self):
4) Test.count
5) @classmethod
=Test.count+1
6) def noOfObjects(cls):
7) print('The number of objects created for test
8) class:',cls.count)
9) t1=Test()
10) t2=Test()
11)
Test.noOfObjects()
12) t3=Test()

13)
14) t4=Test()
t5=Test()

15)
Test.noOfObjects()
3)Static Methods:
⚽ In general these methods are general utility methods.
⚽ Inside these methods we won't use any instance or class variables.
⚽ Here we won't provide self or cls arguments at the time of declaration.
⚽ We can declare static method explicitly by using @staticmethod decorator
⚽ We can access static methods by using classname or object reference

1) class DurgaMath:
2)
3) @staticmethod
4) def add(x,y):
5) print('The Sum:',x+y)
6)

KESA PAVAN KUMAR Cell No: 9848461833


25

7)
8) @staticmeth
def product(x,y):
od
9) print('The
10 Product:',x*y)
)11)
12) @staticmeth
def average(x,y):
od
13 print('The
)
14 average:',(x+y)/2)
)15) DurgaMath.add(10,20)
16) DurgaMath.product(10,20)
17)
DurgaMath.average(10,20)
Output
The Sum: 30
The Product: 200
The average: 15.0

Note:
 In general we can use only instance and static methods.Inside static
method we can access class level variables by using class name.
 Class methods are most rarely used methods in python.

Passing Members of One Class to Another Class:


We can access members of one class inside another class.

1) class
Employee:
2) def init (self,eno,ename,esal):
3) self.eno=e
4) no
self.ename=ena
5) me
self.esal=e
6) sal
def display(self):
7) print('Employee
8) Number:',self.eno)
print('Employee
9) Name:',self.ename)
print('Employee
10) classSalary:',self.esal)
Test:
11) def
modify(emp):
12 emp.esal=emp.esal+10
)13 000
emp.displa
)14) e=Employee(100,'Durga',10000)
y()
15) Test.modify(
e)

KESA PAVAN KUMAR Cell No: 9848461833


26

Output
D:\python_classes>py
test.py Employee
Number: 100 Employee
Name: Durga Employee
Salary: 20000

In the above application, Employee class members are available to Test class.

Inner Classes
Sometimes we can declare a class inside another class, such type of
classes are called inner classes.

Without existing one type of object if there is no chance of existing another


type of object, then we should go for inner classes.

Example: Without existing Car object there is no chance of existing Engine


object. Hence Engine class should be part of Car class.

class Car:
.....
class Engine:
......

Example: Without existing university object there is no chance of existing


Department object

class University:
.....
class Department:
......

Example: Without existing Human there is no chance of existin Head. Hence


Head should be part of Human.

class Human:
class Head:

Note: Without existing outer class object there is no chance of existing inner
class object. Hence inner class object is always associated with outer class
object.

KESA PAVAN KUMAR Cell No: 9848461833


27

Demo Program-1:

1) class
Outer:
2) def init (self):
3) print("outer class object
4) creation")
class Inner:
5) def init (self):
6) print("inner class object
7) creation")
def
8) m1(self):
print("inner class
9) method")
o=Outer()
10) i=o.Inner()

11) i.m1()
Output
outer class object
creation inner class
object creation inner
class method

Note: The following are various possible syntaxes for calling inner class method
1) o =
Outer() i =
o.Inner()
i.m1()

2) i =
Outer().Inner()
i.m1()

3) Outer().Inner().m1()

Demo Program-2:

1) class
Person:
2) def init (self):
3) self.name='dur
4) ga'
self.db=self.Do
5) b()
def
display(self):
6) print('Name:',self.na
me)
7)
8) class Dob:
def init (self):
9) self.dd=1
10 0
self.mm=
)11 5
self.yy=19
)12 47
def
)13 display(self):
print('Dob={}/{}/{}'.format(self.dd,self.mm,sel
) f.yy))
KESA PAVAN KUMAR Cell No: 9848461833
28

14) p=Person()
15) p.display()
16) x=p.db
17) x.display()

Output
Name: durga
Dob=10/5/194
7

Demo Program-3:
Inside a class we can declare any number of inner classes.

1) class Human:
2)
3) def init (self):
4) self.name =
5) 'Sunny'
self.head =
6) self.Head()
self.brain =
7) self.Brain()
def
display(self):
8) print("Hello..",self.na
me)
9)
10) class Head:
11 def
)12 talk(self):
print('Talking..
)13 .')
)
14) class Brain:
def
15
16 think(self):
print('Thinking..
)17) .')
18) h=Human()
19) h.display()
20) h.head.talk()
21)
h.brain.think()
Output
Hello..
Sunny
Talking...
Thinking...

KESA PAVAN KUMAR Cell No: 9848461833


29

Garbage Collection
⚽ In old languages like C++, programmer is responsible for both creation and
destruction of objects.Usually programmer taking very much care while
creating object, but nEglecting destruction of useless objects. Because of
his nEglectance, total memory can be filled with useless objects which
creates memory problems and total application will be down with Out of
memory error.

⚽ But in Python, We have some assistant which is always running in the


background to destroy useless objects.Because this assistant the chance
of failing Python program with memory problems is very less. This
assistant is nothing but Garbage Collector.
⚽ Hence the main objective of Garbage Collector is to destroy useless objects.

⚽ If an object does not have any reference variable then that object eligible
for Garbage Collection.

How to enable and disable Garbage


Collector in our Program:
By default Gargbage collector is enabled, but we can disable based on our
requirement. In this context we can use the following functions of gc module.

1) gc.isenabled()  Returns True if GC enabled

2) gc.disable() To disable GC explicitly

3) gc.enable() To enable GC explicitly

1) import gc
2) print(gc.isenabled())
3) gc.disable()
4) print(gc.isenabled())
5) gc.enable()
6) print(gc.isenabled())

Outpu
t True
False
True

KESA PAVAN KUMAR Cell No: 9848461833


30

Destructors:
⚽ Destructor is a special method and the name should be del
⚽ Just before destroying an object Garbage Collector always calls destructor
to perform clean up activities (Resource deallocation activities like close
database connection etc).
⚽ Once destructor execution completed then Garbage Collector automatically
destroys that object.

Note: The job of destructor is not to destroy object and it is just to perform
clean up activities.
1) import time
2) class Test:
3) def init (self):
4) print("Object
5) def del
Initialization...")
6) print("Fulfilling Last Wish and performing clean up
(self): 7)
activities...")
8)
9) t1=Test()
t1=None

10)
11) time.sleep(5)
print("End of application")

Output
Object Initialization...
Fulfilling Last Wish and performing clean up
activities... End of application

Note: If the object does not contain any reference variable then only it is
eligible fo GC. ie if the reference count is zero then only object eligible for GC.

1) import time
2) class Test:
3) def init (self):
4) print("Constructor Execution...")
5) def del (self):
6) print("Destructor Execution...")
7)
8) t1=Test()
9) t2=t1
10) t3=t2
11) del t1
12) time.sleep(5)
13) print("object not yet destroyed after deleting t1")
14) del t2

KESA PAVAN KUMAR Cell No: 9848461833


31

15) time.sleep(5)
16) print("object not yet destroyed even after deleting t2")
17) print("I am trying to delete last reference variable...")
18) del
t3
Example:

1) import time
2) class Test:
3) def init (self):
4) print("Constructor
5) def del
Execution...")
6) print("Destructor
(self): 7)
Execution...")
8) list=[Test(),Test(),Test()]
9) del list
10) time.sleep(5)
11) print("End of application")

Output
Constructor
Execution...
Constructor
Execution...
Constructor
Execution...
Destructor
Execution...
Destructor
Execution...
Destructor
Execution... End of
application

How to find the Number of References of an Object:


sys module contains getrefcount() function for this
purpose. sys.getrefcount (objectreference)

1) import sys
2) class Test:
3) pass
4) t1=Test()
5) t2=t1
6) t3=t1
7) t4=t1
8) print(sys.getrefcount(t1))

Output 5
KESA PAVAN KUMAR Cell No: 9848461833
32

Note: For every object, Python internally maintains one default reference variable self.

KESA PAVAN KUMAR Cell No: 9848461833


33

OOP’s
Part - 2

KESA PAVAN KUMAR Cell No: 9848461833


34

Agenda

 Inheritance
 Has-A Relationship
 IS-A Relationship
 IS-A vs HAS-A Relationship
 Composition vs Aggregation

 Types of Inheritance
 Single Inheritance
 Multi Level Inheritance
 Hierarchical Inheritance
 Multiple Inheritance
 Hybrid Inheritance
 Cyclic Inheritance

 Method Resolution Order (MRO)


 super() Method

Using Members of One Class inside Another Class:


We can use members of one class inside another class by using the following ways

1) By Composition (Has-A Relationship)


2) By Inheritance (IS-A Relationship)

1) By Composition (Has-A Relationship):


 By using Class Name or by creating object we can access members of
one class inside another class is nothing but composition (Has-A
Relationship).
 The main advantage of Has-A Relationship is Code Reusability.

Demo Program-1:

1) class Engine:
2) a=10
3) def init (self):
4) self.b=2
5) def
0 m1(self):

KESA PAVAN KUMAR Cell No: 9848461833


35

6) print('Engine Specific Functionality')


7) class Car:
8) def init (self):
9) self.engine=Engine()
10 def m2(self):
)
11 print('Car using Engine Class Functionality')
)
12 print(self.engine.a)
)
13 print(self.engine.b)
)
14 self.engine.m1()
)
15) c=Car()
16) c.m2()

Output:
Car using Engine Class
Functionality 10
20
Engine Specific Functionality

Demo Program-2:

1) class
Car: def init (self,name,model,color):
2)
3) self.name=na
4) me
self.model=mo
5) del
self.color=col
6) orgetinfo(self):
def
7) print("Car Name:{} , Model:{} and
Color:{}".format(self.name,self.model,self.c
8) olor))

9)
10)class def Employee:
init (self,ename,eno,car):
11 self.ename=ena
)12 me
self.eno=e
)13 no
self.car=c
)14) def arempinfo(self):
15 print("Employee
)
16 Name:",self.ename)
print("Employee
)17 Number:",self.eno)
print("Employee Car
)18 Info:")
self.car.getinf
)19) o()
c=Car("Innova","2.5V","Grey"
20) e=Employee('Durga',10000,c)
)21) e.empinfo
()
KESA PAVAN KUMAR Cell No: 9848461833
36

Output:
Employee Name:
Durga Employee
Number: 10000
Employee Car Info:
Car Name: Innova, Model: 2.5V and Color:Grey

In the above program Employee class Has-A Car reference and hence
Employee class can access all members of Car class.

Demo Program-3:

1) class
X: a=10
2)
3) def init (self):
4) self.b=2
5) 0 m1(self):
def
6) print("m1 method of X
7) class")
8) class Y:
9) c=30
10) def init (self):
11 self.d=4
)12) def 0 m2(self):
13 print("m2 method of Y
) class")
14
15) def m3(self):
)16 x1=X(
)17 )print(x1.
)18 a)
print(x1.
)19 b)
x1.m1(
)20 )print(Y.
)21 c)
print(self.
)22 d)
self.m2
)23 ()
print("m3 method of Y
)24) y1=Y()
class")
25) y1.m3(
)
Output:
10
20
m1 method of X
class 30
40
m2 method of Y
class m3 method
of Y class

KESA PAVAN KUMAR Cell No: 9848461833


37

2) By Inheritance (IS-A Relationship):


What ever variables, methods and constructors available in the parent
class by default available to the child classes and we are not required to
rewrite. Hence the main advantage of inheritance is Code Reusability and
we can extend existing functionality with some more extra functionality.

Syntax: class childclass(parentclass)


1) class P:
2) a=10
3) def init (self):
4) self.b=10
5) def m1(self):
6) print('Parent instance method')
7) @classmethod
8) def m2(cls):
9) print('Parent class method')
10) @staticmethod
11) def m3():
12 print('Parent static method')
)
13)
14) class C(P):
15) pass
16)
17) c=C()
18) print(c.a)
19) print(c.b)
20) c.m1()
21) c.m2()
22) c.m3()

Output:
10
10
Parent instance
method Parent class
method Parent static
method

1) class P:
2) 10 methods
3) class C(P):
4) 5 methods

KESA PAVAN KUMAR Cell No: 9848461833


38

In the above example Parent class contains 10 methods and these methods
automatically available to the child class and we are not required to rewrite
those methods(Code Reusability)
Hence child class contains 15 methods.

Note: What ever members present in Parent class are by default available to
the child class through inheritance.

1) class P:
2) def m1(self):
3) print("Parent class method")
4) class C(P):
5) def m2(self):
6) print("Child class method")
7)
8) c=C();
9) c.m1()
10) c.m2()

Output:
Parent class
method Child
class method

What ever methods present in Parent class are automatically available to the
child class and hence on the child class reference we can call both parent
class methods and child class methods.

Similarly variables also

1) class P:
2) a=10
3) def init (self):
4) self.b=20
5) class C(P):
6) c=30
7) def init (self):
8) super(). init ()===>Line-1
9) self.d=30
10)
11) c1=C()
12) print(c1.a,c1.b,c1.c,c1.d)

If we comment Line-1 then variable b is not available to the child class.

KESA PAVAN KUMAR Cell No: 9848461833


39

Demo program for Inheritance:


1) class Person:
2) def init (self,name,age):
3) self.name=name
4) self.age=age
5) def eatndrink(self):
6) print('Eat Biryani and Drink
Beer') 7)
8) class Employee(Person):
9) def init (self,name,age,eno,esal):
10) super(). init (name,age)
11) self.eno=eno
12) self.esal=e
sal 13)
14) def work(self):
15) print("Coding Python is very easy just like drinking Chilled Beer")
16) def empinfo(self):
17) print("Employee Name:",self.name)
18) print("Employee Age:",self.age)
19) print("Employee Number:",self.eno)
20) print("Employee
Salary:",self.esal) 21)
22) e=Employee('Durga', 48, 100, 10000)
23) e.eatndrink()
24) e.work()
25) e.empinfo()

Output:
Eat Biryani and Drink Beer
Coding Python is very easy just like drinking Chilled
Beer Employee Name: Durga
Employee Age: 48
Employee Number: 100
Employee Salary: 10000

IS-A vs HAS-A Relationship:


 If we want to extend existing functionality with some more extra
functionality then we should go for IS-A Relationship.
 If we dont want to extend and just we have to use existing
functionality then we should go for HAS-A Relationship.
 Eg: Employee class extends Person class Functionality But Employee
class just uses Car functionality but not extending

KESA PAVAN KUMAR Cell No: 9848461833


40

Person

IS - A

HAS - A
Employee Ca
r

1) class Car:
2) def init (self,name,model,color):
3) self.name=name
4) self.model=model
5) self.color=color
6) def getinfo(self):
7) print("\tCar Name:{} \n\t Model:{} \n\t
Color:{}".format(self.name,self.model,
self.color))
8)
9) class Person:
10) def init (self,name,age):
11) self.name=name
12) self.age=age
13) def eatndrink(self):
14) print('Eat Biryani and Drink Beer')
15)
16) class Employee(Person):
17) def init (self,name,age,eno,esal,car):
18) super(). init (name,age)
19) self.eno=eno
20) self.esal=esal
21) self.car=car
22) def work(self):
23) print("Coding Python is very easy just like drinking Chilled Beer")
24) def empinfo(self):
25) print("Employee Name:",self.name)
26) print("Employee Age:",self.age)
27) print("Employee Number:",self.eno)
28) print("Employee Salary:",self.esal)
29) print("Employee Car Info:")
30) self.car.getinfo()
31)
32) c=Car("Innova","2.5V","Grey")
33) e=Employee('Durga',48,100,10000,c)
34) e.eatndrink()

KESA PAVAN KUMAR Cell No: 9848461833


41

35) e.work()
36) e.empinfo()

Output:
Eat Biryani and Drink Beer
Coding Python is very easy just like drinking Chilled
Beer Employee Name: Durga
Employee Age: 48
Employee Number: 100
Employee Salary:
10000 Employee Car
Info:
Car
Name:Innova
Model:2.5V
Color:Grey

In the above example Employee class extends Person class functionality but
just uses Car class functionality.

Composition vs Aggregation:

Composition:
Without existing container object if there is no chance of existing contained
object then the container and contained objects are strongly associated and
that strong association is nothing but Composition.

Eg: University contains several Departments and without existing university


object there is no chance of existing Department object. Hence University and
Department objects are strongly associated and this strong association is
nothing but Composition.

Department
Object
(Contained
Object)

University
Object
(Container
KESA PAVAN KUMAR Cell No: 9848461833
42

Object)

KESA PAVAN KUMAR Cell No: 9848461833


43

Aggregation:
Without existing container object if there is a chance of existing contained
object then the container and contained objects are weakly associated and
that weak association is nothing but Aggregation.

Eg: Department contains several Professors. Without existing Department still


there may be a chance of existing Professor. Hence Department and Professor
Objects are weakly associated, which is nothing but Aggregation.

(Contained
x

Professor
: :

Object)
Object
: :
: :
x

Department
Object
(Container
Object)

Coding Example:

1) class Student:
2) collegeName='DURGASOFT'
3) def init (self,name):
4) self.name=na
5) print(Student.collegeName)
me
6) s=Student('Durga')
7) print(s.name)

Output:
DURGASOFT
Durga

In the above example without existing Student object there is no chance of


existing his name. Hence Student Object and his name are strongly
associated which is nothing but Composition.

But without existing Student object there may be a chance of existing


collegeName. Hence Student object and collegeName are weakly associated
which is nothing but Aggregation.

KESA PAVAN KUMAR Cell No: 9848461833


44

Conclusion:
The relation between object and its instance variables is always Composition
where as the relation between object and static variables is Aggregation.

Note: Whenever we are creating child class object then child class
constructor will be executed. If the child class does not contain constructor
then parent class constructor will be executed, but parent object won't be
created.

1) class P:
2) def init (self):
3) print(id(self))
4) class C(P):
5) pass
6) c=C()
7) print(id(c))

Output:
6207088
6207088

1) class
Person:
2) def init (self,name,age):
3) self.name=na
4) me
self.age=a
5) classge
Student(Person):
6) def init (self,name,age,rollno,marks):
7) super(). init (name,age)
8) self.rollno=roll
9) no
self.marks=mar
ks
10) def str (self):
11) return
'Name={}\nAge={}\nRollno={}\nMarks={}'.format(self.name,self.age,sel
12) f.rollno,self.marks)
s1=Student('durga',48,101,90)

13) print(s1)
Output:
Name=dur
ga Age=48
Rollno=101
Marks=90

Note: In the above example when ever we are creating child class object both
parent and child class constructors got executed to perform initialization of
child object.

KESA PAVAN KUMAR Cell No: 9848461833


45

Types of Inheritance:
1)Single Inheritance:
The concept of inheriting the properties from one class to another class is
known as single inheritance.

1) class
P:
2) def m1(self):
3) print("Parent
4) classMethod")
C(P):
5) def
m2(self):
6) print("Child
Method")
7) c=C()
8) c.m1()
9) c.m2()
Output:
Parent
Method Child
Method

Single Inheritance

2)Multi Level Inheritance:


The concept of inheriting the properties from multiple classes to single
class with the concept of one after another is known as multilevel
inheritance.

1) class P:
2) def m1(self):
3) print("Parent Method")
4) class C(P):
5) def m2(self):
6) print("Child Method")
7) class CC(C):
8) def m3(self):
9) print("Sub Child Method")
10) c=CC()

KESA PAVAN KUMAR Cell No: 9848461833


46

11) c.m1()
12) c.m2()
13) c.m3()

Output:
Parent
Method Child
Method
Sub Child Method

C Multi – Level Inheritance

C
C

3)Hierarchical Inheritance:
The concept of inheriting properties from one class into multiple classes
which are present at same level is known as Hierarchical Inheritance

C C
1 2
Hierarchical
Inheritance

1) class P:
2) def m1(self):
3) print("Parent Method")
4) class C1(P):

KESA PAVAN KUMAR Cell No: 9848461833


47

5) def
m2(self):
6) print("Child1
Method")
7) class
8) def C2(P):
m3(self):
9) print("Child2
Method")
10) c1=C1()
11)
c1.m1()
12) c1.m2()

13)
14) c2.m1()
c2=C2()

15)
Output:
c2.m3()
Parent
Method
Child1
Method
Parent
Method
Child2
Method

4)Multiple Inheritance:
The concept of inheriting the properties from multiple classes into a single
class at a time, is known as multiple inheritance.

P P
1 2

Multiple
Inheritanc
e

1) class
P1: def m1(self):
2)
3) print("Parent1
4) classMethod")
P2:
5) def
m2(self):
6) print("Parent2
Method")
7)
8) class
def m3(self):
KESA PAVAN KUMAR
C(P1,P2): Cell No: 9848461833
9) print("Child2
Method")
48

10) c=C()
11) c.m1()
12) c.m2()
13) c.m3()

Output:
Parent1
Method
Parent2
Method
Child2
Method

If the same method is inherited from both parent classes, then Python
will always consider the order of Parent classes in the declaration of
the child class.

class C(P1, P2):  P1 method will be


considered class C(P2, P1):  P2 method
will be considered

1) class P1:
2) def m1(self):
3) print("Parent1 Method")
4) class P2:
5) def m1(self):
6) print("Parent2 Method")
7) class C(P1,P2):
8) def m2(self):
9) print("Child Method")
10) c=C()
11) c.m1()
12) c.m2()

Output:
Parent1
Method Child
Method

KESA PAVAN KUMAR Cell No: 9848461833


49

5)Hybrid Inheritance:
Combination of Single, Multi level, multiple and Hierarchical inheritance is
known as Hybrid Inheritance.

A B C

G H

6)Cyclic Inheritance:
The concept of inheriting properties from one class to another class in
cyclic way, is called Cyclic inheritance.Python won't support for Cyclic
Inheritance of course it is really not required.
Eg - 1: class A(A):pass
NameError: name 'A' is not defined

Eg - 2:

1) class A(B):
2) pass
3) class B(A):
4) pass

NameError: name 'B' is not defined

KESA PAVAN KUMAR Cell No: 9848461833


50

Method Resolution Order (MRO):


 In Hybrid Inheritance the method resolution order is decided
based on MRO algorithm.
 This algorithm is also known as C3 algorithm.
 Samuele Pedroni proposed this algorithm.
 It follows DLR (Depth First Left to Right) i.e Child will get more priority than Parent.
 Left Parent will get more priority than Right Parent.
 MRO(X) = X+Merge(MRO(P1),MRO(P2),...,ParentList)

Head Element vs Tail Terminology:


 Assume C1,C2,C3,...are classes.
 In the list: C1C2C3C4C5....
 C1 is considered as Head Element and remaining is considered as Tail.

How to find Merge:


 Take the head of first list
 If the head is not in the tail part of any other list, then add this head to the
result and remove it from the lists in the merge.
 If the head is present in the tail part of any other list, then consider the
head element of the next list and continue the same process.

Note: We can find MRO of any class by using mro()


function. print(ClassName.mro())

KESA PAVAN KUMAR Cell No: 9848461833


51

Demo Program-1 for Method Resolution Order:

B C

D
mro(A) = A, object
mro(B) = B, A, object
mro(C) = C, A, object
mro(D) = D, B, C, A,
object

test.py
1) class A:pass
2) class B(A):pass
3) class C(A):pass
4) class D(B,C):pass
5) print(A.mro())
6) print(B.mro())
7) print(C.mro())
8) print(D.mro())

Output:
[<class ' main .A'>, <class 'object'>]
[<class ' main .B'>, <class ' main .A'>, <class
'object'>] [<class ' main .C'>, <class ' main .A'>,
<class 'object'>]
[<class ' main .D'>, <class ' main .B'>, <class ' main .C'>, <class ' main .A'>,
<class 'object'>]

KESA PAVAN KUMAR Cell No: 9848461833


52

Demo Program-2 for Method Resolution Order:

Objec
t

A B C

X Y

mro(A)=A,object P
mro(B)=B,object
mro(C)=C,object
mro(X)=X,A,B,object
mro(Y)=Y,B,C,object
mro(P)=P,X,A,Y,B,C,ob
ject

Finding mro(P) by using C3 Algorithm:


Formula: MRO(X) =
X+Merge(MRO(P1),MRO(P2),...,ParentList)
mro(p) = P+Merge(mro(X),mro(Y),mro(C),XYC)
= P+Merge(XABO,YBCO,CO,XYC)
= P+X+Merge(ABO,YBCO,CO,YC)
= P+X+A+Merge(BO,YBCO,CO,YC)
= P+X+A+Y+Merge(BO,BCO,CO,C)
= P+X+A+Y+B+Merge(O,CO,CO,C)
= P+X+A+Y+B+C+Merge(O,O,O)
= P+X+A+Y+B+C+O

test.py
1) class A:pass
2) class B:pass
3) class C:pass
4) class X(A,B):pass
5) class Y(B,C):pass
6) class P(X,Y,C):pass

KESA PAVAN KUMAR Cell No: 9848461833


53

7) print(A.mro())#AO
8) print(X.mro())#XABO
9) print(Y.mro())#YBCO
10) print(P.mro())#PXAYBCO

Output:
[<class ' main .A'>, <class 'object'>]
[<class ' main .X'>, <class ' main .A'>, <class ' main .B'>, <class
'object'>] [<class ' main .Y'>, <class ' main .B'>, <class ' main
.C'>, <class 'object'>] [<class ' main .P'>, <class ' main .X'>, <class ' main
.A'>, <class ' main .Y'>,
<class ' main .B'>,
<class ' main .C'>, <class 'object'>]

test.py
1) class A:
2) def m1(self):
3) print('A class Method')
4) class B:
5) def m1(self):
6) print('B class Method')
7) class C:
8) def m1(self):
9) print('C class Method')
10) class X(A,B):
11) def m1(self):
12 print('X class Method')
)
13) class Y(B,C):
14) def m1(self):
15 print('Y class Method')
)
16) class P(X,Y,C):
17) def m1(self):
18 print('P class Method')
)
19) p=P()
20) p.m1()

Output: P class Method


In the above example P class m1() method will be considered.If P class does
not contain m1() method then as per MRO, X class method will be considered.
If X class does not contain then A class method will be considered and this
process will be continued.

The method resolution in the following order: PXAYBCO

KESA PAVAN KUMAR Cell No: 9848461833


54

Demo Program-3 for Method Resolution Order:

Objec
t

D E F

B C

mro(o) = object
mro(D) = D,object
mro(E) = E,object
mro(F) = F,object
mro(B) =
B,D,E,object
mro(C) =
C,D,F,object
mro(A) = A+Merge(mro(B),mro(C),BC)
= A+Merge(BDEO,CDFO,BC)
= A+B+Merge(DEO,CDFO,C)
= A+B+C+Merge(DEO,DFO)
= A+B+C+D+Merge(EO,FO)
= A+B+C+D+E+Merge(O,FO)
= A+B+C+D+E+F+Merge(O,O)
= A+B+C+D+E+F+O

test.py
1) class D:pass
2) class E:pass
3) class F:pass
4) class B(D,E):pass
5) class C(D,F):pass
6) class A(B,C):pass
7) print(D.mro())
8) print(B.mro())

KESA PAVAN KUMAR Cell No: 9848461833


55

9) print(C.mro())
10) print(A.mro())

Output:
[<class ' main .D'>, <class 'object'>]
[<class ' main .B'>, <class ' main .D'>, <class ' main .E'>, <class
'object'>] [<class ' main .C'>, <class ' main .D'>, <class ' main
.F'>, <class 'object'>] [<class ' main .A'>, <class ' main .B'>, <class ' main
.C'>, <class ' main .D'>,
<class ' main .E'>,
<class ' main .F'>, <class 'object'>]

super() Method:
super() is a built-in method which is useful to call the super class
constructors,variables and methods from the child class.

Demo Program-1 for super():


1) class
Person:
2) def init (self,name,age):
3) self.name=na
4) me
self.age=a
5) gedisplay(self):
def
6) print('Name:',self.na
7) me)
print('Age:',self.a
8) ge)
9) class Student(Person):
10) def init (self,name,age,rollno,marks):
11 super(). init (name,age)
)12 self.rollno=roll
)13 no
self.marks=mar
)14 ks
)15) def display(self):
16 super().displa
)17 y()
print('Roll
)18 No:',self.rollno)
print('Marks:',self.mar
) ks)
19
20)
)s1=Student('Durga',22,101,90)
21)
s1.display()
Output:
Name:
Durga Age:
22
Roll No: 101
Marks: 90

KESA PAVAN KUMAR Cell No: 9848461833


56

In the above program we are using super() method to call parent class
constructor and display() method

Demo Program-2 for super():


1) class P:
2) a=10
3) def init (self):
4) self.b=10
5) def m1(self):
6) print('Parent instance method')
7) @classmethod
8) def m2(cls):
9) print('Parent class method')
10) @staticmethod
11) def m3():
12 print('Parent static method')
)
13)
14) class C(P):
15) a=888
16) def init (self):
17 self.b=999
)
18 super(). init ()
)
19 print(super().a)
)
20 super().m1()
)
21 super().m2()
)
22 super().m3()
)
23)
24) c=C()

Output:
10
Parent instance
method Parent class
method Parent static
method

In the above example we are using super() to call various members of Parent class.

KESA PAVAN KUMAR Cell No: 9848461833


57

How to Call Method of a Particular Super Class:


We can use the following approaches

1) super(D, self).m1()
It will call m1() method of super class of D.

2) A.m1(self)
It will call A class m1() method

1) class A:
2) def m1(self):
3) print('A class Method')
4) class B(A):
5) def m1(self):
6) print('B class Method')
7) class C(B):
8) def m1(self):
9) print('C class Method')
10) class D(C):
11) def m1(self):
12) print('D class Method')
13) class E(D):
14) def m1(self):
15) A.m1(self)
16)
17) e=E()
18) e.m1()

Output: A class Method

Various Important Points about super():


Case-1: From child class we are not allowed to access parent class instance
variables by using super(), Compulsory we should use self only.
But we can access parent class static variables by using super().

1) class P:
2) a=10
3) def init
4) self.b=2
(self): 5)
0
6) class C(P):
7) def m1(self):

KESA PAVAN KUMAR Cell No: 9848461833


58

8) print(super().a)#valid
9) print(self.b)#valid
10) print(super().b)#invalid
11) c=C()
12) c.m1()

Output:
10
20
AttributeError: 'super' object has no attribute 'b'

Case-2: From child class constructor and instance method, we can access
parent class instance method, static method and class method by using
super()

1) class
P:
2) def init (self):
3) print('Parent
4) Constructor')
def m1(self):
5) print('Parent instance
6) method')
@classmethod
7) def m2(cls):
8) print('Parent class
9) method')
10) def @staticmeth
m3():
od
11 print('Parent static
)
12 method')
)13) class
C(P):
14) def init (self):
15 super(). init ()
)16 super().m1
)17 ()
super().m2
)
18 ()
super().m3
)19 ()
)20) def m1(self):
super(). init ()
21
22 super().m1
)23 ()
super().m2
)
24 ()
super().m3
)25) ()
26) c=C()
27)
c.m1()

KESA PAVAN KUMAR Cell No: 9848461833


59

Output:
Parent Constructor
Parent instance
method Parent class
method Parent static
method Parent
Constructor Parent
instance method
Parent class method
Parent static method

Case-3: From child class, class method we cannot access parent class
instance methods and constructors by using super() directly(but indirectly
possible). But we can access parent class static and class methods.

1) class
P:
2) def init (self):
3) print('Parent
4) defConstructor')
m1(self):
5) print('Parent instance
6) method')
@classmethod
7) def m2(cls):
8) print('Parent class
9) method')
10) def @staticmeth
m3():
od
11 print('Parent static
)12 method')
)13) class C(P):
14) @classmethod
15) def
m1(cls):
16 #super(). init ()--->invalid
)17 #super().m1()---
)18 >invalid
super().m2
)19 ()
super().m3
)20 ()
)21)
C.m1()
Output:
Parent class
method Parent
static method

KESA PAVAN KUMAR Cell No: 9848461833


60

From Class Method of Child Class, how to call Parent Class


Instance Methods and Constructors:
1) class A:
2) def init (self):
3) print('Parent constructor')
4)
5) def m1(self):
6) print('Parent instance method')
7)
8) class B(A):
9) @classmethod
10) def m2(cls):
11) super(B,cls). init (cls)
12) super(B,cls).m1(cls)
13)
14) B.m2()

Output:
Parent constructor
Parent instance
method

Case-4: In child class static method we are not allowed to use super()
generally (But in special way we can use)

1) class P:
2) def init (self):
3) print('Parent Constructor')
4) def m1(self):
5) print('Parent instance method')
6) @classmethod
7) def m2(cls):
8) print('Parent class method')
9) @staticmethod
10) def m3():
11) print('Parent static method')
12)
13) class C(P):
14) @staticmethod
15) def m1():
16) super().m1()-->invalid
17) super().m2()--->invalid
18) super().m3()--->invalid
19)
20) C.m1()

KESA PAVAN KUMAR Cell No: 9848461833


61

RuntimeError: super(): no arguments

How to Call Parent Class Static Method from Child


Class Static Method by using super():
1) class A:
2)
3) @staticmethod
4) def m1():
5) print('Parent static method')
6)
7) class B(A):
8) @staticmethod
9) def m2():
10) super(B,B).m1()
11)
12) B.m2()

Output: Parent static method

KESA PAVAN KUMAR Cell No: 9848461833


62

OOP’s
Part - 3

KESA PAVAN KUMAR Cell No: 9848461833


63

POLYMORPHISM
poly means many. Morphs means
forms. Polymorphism means 'Many
Forms'.

Eg1: Yourself is best example of polymorphism.In front of Your parents You


will have one type of behaviour and with friends another type of
behaviour.Same person but different behaviours at different places,which is
nothing but polymorphism.

Eg2: + operator acts as concatenation and arithmetic

addition Eg3: * operator acts as multiplication and

repetition operator

Eg4: The Same method with different implementations in Parent class and
child classes.(overriding)

Related to Polymorphism the following 4 topics are important

1) Duck Typing Philosophy of Python

2) Overloading
1) Operator Overloading
2) Method Overloading
3) Constructor Overloading

3) Overriding
1) Method Overriding
2) Constructor Overriding

1) Duck Typing Philosophy of Python:


In Python we cannot specify the type explicitly. Based on provided
value at runtime the type will be considered automatically. Hence
Python is considered as Dynamically Typed Programming Language.

def
f1(obj):
obj.talk()

What is the Type of obj? We cannot decide at the Beginning. At


Runtime we can Pass any Type. Then how we can decide the
Type?
At runtime if 'it walks like a duck and talks like a duck,it must be duck'. Python
KESA PAVAN KUMAR Cell No: 9848461833
64

follows this principle. This is called Duck Typing Philosophy of Python.

KESA PAVAN KUMAR Cell No: 9848461833


65

1) class Duck:
2) def talk(self):
3) print('Quack.. Quack..')
4)
5) class Dog:
6) def talk(self):
7) print('Bow Bow..')
8)
9) class Cat:
10) def talk(self):
11) print('Moew Moew ..')
12)
13) class Goat:
14) def talk(self):
15) print('Myaah Myaah ..')
16)
17) def f1(obj):
18) obj.talk()
19)
20) l=[Duck(),Cat(),Dog(),Goat()]
21) for obj in l:
22) f1(obj)

Output:
Quack..
Quack..
Moew Moew
.. Bow Bow..
Myaah Myaah ..

The problem in this approach is if obj does not contain talk() method then we
will get AttributeError.

1) class
Duck:
2) def talk(self):
3) print('Quack..
4) Quack..')
5) class
Dog:
6) def bark(self):
7) print('Bow
Bow..')
8) def f1(obj):
9)
10 obj.talk(
)
12) f1(d)
11) d=Duck()

13)
KESA PAVAN KUMAR Cell No: 9848461833
66

14) d=Dog()
15) f1(d)

Output:
D:\durga_classes>py
test.py Quack.. Quack..
Traceback (most recent call last):
File "test.py", line 22, in
<module> f1(d)
File "test.py", line 13,
in f1 obj.talk()
AttributeError: 'Dog' object has no attribute 'talk'

But we can solve this problem by using hasattr() function.

hasattr(obj,'attributename')  attributename can be Method Name OR Variable Name

Demo Program with hasattr() Function:


1) class
Duck:
2) def talk(self):
3) print('Quack..
4) Quack..')
5) class
Human:
6) def talk(self):
7) print('Hello
8) Hi...')
9) class
Dog:
10) def bark(self):
11 print('Bow
)
12 Bow..')
)13) def
f1(obj):
14) if hasattr(obj,'talk'):
15 obj.talk(
)16) elif ) hasattr(obj,'bark'):
17 obj.bark
)
18 ()
)19)
d=Duck()
20) f1(d)

21)
22) h=Human()
23)
24 f1(h)
)
25)
26) f1(d)
d=Dog()

KESA PAVAN KUMAR Cell No: 9848461833


67

27) Myaah Myaah Myaah...

2) Overloading
We can use same operator or methods for different purposes.

Eg 1: + operator can be used for Arithmetic addition and String concatenation


print(10+20)#30
print('durga'+'soft')#durgasoft

Eg 2: * operator can be used for multiplication and string repetition purposes.


print(10*20)#200
print('durga'*3)#durgadurgadurga

Eg 3: We can use deposit() method to deposit cash or cheque or dd


deposit(cash)
deposit(chequ
e) deposit(dd)

There are 3 types of Overloading


1) Operator Overloading
2) Method Overloading
3) Constructor Overloading

1)Operator Overloading:
 We can use the same operator for multiple purposes, which is nothing
but operator overloading.
 Python supports operator overloading.

Eg 1: + operator can be used for Arithmetic addition and String


concatenation print(10+20)#30
print('durga'+'soft')#durgasoft

Eg 2: * operator can be used for multiplication and string repetition purposes.


print(10*20)#200
print('durga'*3)#durgadurgadurga

Demo program to use + operator for our class


objects:
1) class
Book:
2) def init (self,pages):
3) self.pages=pa
4) ges
5)
b1=Book(100)

KESA PAVAN KUMAR Cell No: 9848461833


68

6) b2=Book(200)
7) print(b1+b2)

D:\durga_classes>py test.py
Traceback (most recent call
last):
File "test.py", line 7, in
<module> print(b1+b2)
TypeError: unsupported operand type(s) for +: 'Book' and 'Book'

⚽ We can overload + operator to work with Book objects also. i.e Python
supports Operator Overloading.
⚽ For every operator Magic Methods are available. To overload any operator
we have to override that Method in our class.
⚽ Internally + operator is implemented by using add () method.This method is
called magic method for + operator. We have to override this method in
our class.

Demo Program to Overload + Operator for Our Book Class


Objects:
1) class Book:
2) def init (self,pages):
3) self.pages=pages
4)
5) def add (self,other):
6) return
7) self.pages+other.pages
8) b1=Book(100)
9) b2=Book(200)
10) print('The Total Number of Pages:',b1+b2)

Output: The Total Number of Pages: 300


The following is the list of operators and corresponding magic methods.

1) +  object. add (self,other)


2) -  object. sub (self,other)
3) *  object. mul (self,other)
4) /  object. div (self,other)
5) //  object. floordiv (self,other)
 object. mod (self,other)
6) % 
 object. pow (self,other)
7) **  object. iadd (self,other)
8) +=  object. isub (self,other)
9) -=  object. imul (self,other)
10) *=  object. idiv (self,other)
11) /=  object. ifloordiv
12) //=  (self,other)

KESA PAVAN KUMAR Cell No: 9848461833


69

13)  object. imod (self,other)


%=  object. ipow (self,other)
14) **=  object. lt (self,other)
15) < 
 object. le (self,other)
16) <=
 object. gt (self,other)
17) >
18)  object. ge (self,other)
>=  object. eq (self,other)
19)  object. ne (self,other)
==
20)
!=

Overloading > and <= Operators for Student Class


Objects:
1) class
Student:
2) def init (self,name,marks):
3) self.name=na
4) me
self.marks=mar
5) ksgt (self,other):
def
6) return
7) self.marks>other.marks
def le (self,other):
8) return
9)
self.marks<=other.marks 10)
11) s1=Student("Durga",100)
print("10>20 =",10>20)
13) print("s1>s2=",s1>s2)
12) s2=Student("Ravi",200)
15)
14) print("s1<=s2=",s1<=s2)
print("s1<s2=",s1<s2)

16) print("s1>=s2=",s1>=s2)
Output
10>20 =
False
s1>s2=
False
s1<s2=
True
s1<=s2=
True
s1>=s2=
False

Program to Overload Multiplication Operator to Work on Employee


Objects:

KESA PAVAN KUMAR Cell No: 9848461833


70

1) class
Employee:
2) def init (self,name,salary):
3) self.name=na
4) me
self.salary=sal
5) ary
def mul (self,other):
6) return
7) self.salary*other.days

KESA PAVAN KUMAR Cell No: 9848461833


71

8) class TimeSheet:
9) def init (self,name,days):
10) self.name=name
11) self.days=days
12)
13) e=Employee('Durga',500)
14) t=TimeSheet('Durga',25)
15) print('This Month Salary:',e*t)

Output: This Month Salary: 12500

2)Method Overloading:
 If 2 methods having same name but different type of arguments then
those methods are said to be overloaded methods.
Eg: m1(int a)
m1(double
d)

 But in Python Method overloading is not possible.


 If we are trying to declare multiple methods with same name and different
number of arguments then Python will always consider only last method.

Demo Program:
1) class Test:
2) def m1(self):
3) print('no-arg method')
4) def m1(self,a):
5) print('one-arg method')
6) def m1(self,a,b):
7) print('two-arg method')
8)
9) t=Test()
10) #t.m1()
11) #t.m1(10)
12) t.m1(10,20)

Output: two-arg method

In the above program python will consider only last method.

How we can handle Overloaded Method Requirements in Python:


Most of the times, if method with variable number of arguments required then
we can handle with default arguments or with variable number of argument
methods.

KESA PAVAN KUMAR Cell No: 9848461833


72

Demo Program with Default Arguments:


1) class
Test:
2) def sum(self,a=None,b=None,c=None):
3) if a!=None and b!= None and c!=
4) None:
print('The Sum of 3
5) Numbers:',a+b+c)
elif a!=None and b!=
6) None:
print('The Sum of 2
7) Numbers:',a+b)
else
8) : print('Please provide 2 or 3
9) arguments')
t=Test()
10) t.sum(10,20)
11) t.sum(10,20,30)
12)
t.sum(10)
Output
The Sum of 2 Numbers: 30
The Sum of 3 Numbers: 60
Please provide 2 or 3 arguments

Demo Program with Variable Number of Arguments:


1) class
Test:def sum(self,*a):
2)
3) total=
4) 0
for x in
5) a:total=total+x
6) print('The
7) Sum:',total)
8) t=Test()
9) t.sum(10,20)
10)
t.sum(10,20,30)
11) t.sum(10)

12) t.sum()
3)Constructor Overloading:
⚽ Constructor overloading is not possible in Python.
⚽ If we define multiple constructors then the last constructor will be considered.

1) class Test:
2) def init (self):
3) print('No-Arg Constructor')
4)

KESA PAVAN KUMAR Cell No: 9848461833


73

5) def init (self,a):


6) print('One-Arg constructor')
7)
8) def init (self,a,b):
9) print('Two-Arg constructor')
10) #t1=Test()
11) #t1=Test(10)
12) t1=Test(10,20)

Output: Two-Arg constructor

 In the above program only Two-Arg Constructor is available.


 But based on our requirement we can declare constructor with default
arguments and variable number of arguments.

Constructor with Default Arguments:


1) class Test:
2) def init (self,a=None,b=None,c=None):
3) print('Constructor with 0|1|2|3 number of arguments')
4)
5) t1=Test()
6) t2=Test(10)
7) t3=Test(10,20)
8) t4=Test(10,20,30)

Output
Constructor with 0|1|2|3 number of
arguments Constructor with 0|1|2|3
number of arguments Constructor with
0|1|2|3 number of arguments Constructor
with 0|1|2|3 number of arguments

Constructor with Variable Number of Arguments:


1) class
Test:def init (self,*a):
2)
3) print('Constructor with variable number of
4) arguments')
5) t1=Test()
6) t2=Test(10)
7) t3=Test(10,20)
8) t4=Test(10,20,30)
9)
t5=Test(10,20,30,40,50,60)

KESA PAVAN KUMAR Cell No: 9848461833


74

Output:
Constructor with variable number of
arguments Constructor with variable
number of arguments Constructor with
variable number of arguments
Constructor with variable number of
arguments Constructor with variable
number of arguments

3) Overriding

Method Overriding
⚽ What ever members available in the parent class are bydefault available to
the child class through inheritance. If the child class not satisfied with
parent class implementation then child class is allowed to redefine that
method in the child class based on its requirement. This concept is called
overriding.
⚽ Overriding concept applicable for both methods and constructors.

Demo Program for Method Overriding:


1) class P:
2) def property(self):
3) print('Gold+Land+Cash+Power')
4) def marry(self):
5) print('Appalamma')
6) class C(P):
7) def marry(self):
8) print('Katrina Kaif')
9)
10) c=C()
11) c.property()
12) c.marry()

Output
Gold+Land+Cash+Po
wer Katrina Kaif

From Overriding method of child class,we can call parent class method also
by using super() method.

1) class P:
2) def property(self):
3) print('Gold+Land+Cash+Power')

KESA PAVAN KUMAR Cell No: 9848461833


75

4) def marry(self):
5) print('Appalamma')
6) class C(P):
7) def marry(self):
8) super().marry()
9) print('Katrina Kaif')
10)
11) c=C()
12) c.property()
13) c.marry()

Output
Gold+Land+Cash+Po
wer Appalamma
Katrina Kaif

Demo Program for Constructor Overriding:


1) class
P:
2) def init (self):
3) print('Parent
4) Constructor')
5) class
C(P):
6) def init (self):
7) print('Child
8) Constructor')
9)
c=C()
Output: Child Constructor
In the above example,if child class does not contain constructor then
parent class constructor will be executed

From child class constuctor we can call parent class constructor by using super()
method.

Demo Program to call Parent Class Constructor by using super():


1) class Person:
2) def init (self,name,age):
3) self.name=name
4) self.age=age
5)
6) class Employee(Person):
7) def init (self,name,age,eno,esal):
8) super(). init (name,age)

KESA PAVAN KUMAR Cell No: 9848461833


76

9) self.eno=e
10 no
self.esal=e
)11 sal
)
12) def display(self):
print('Employee
13
14 Name:',self.name)
print('Employee
)15 Age:',self.age)
print('Employee
)
16 Number:',self.eno)
print('Employee
)17) Salary:',self.esal)
18) e1=Employee('Durga',48,872425,26000)
19)
e1.display()
20) e2=Employee('Sunny',39,872426,36000)

21)
e2.display()
Output
Employee Name:
Durga Employee
Age: 48
Employee Number: 872425
Employee Salary: 26000

Employee Name:
Sunny Employee
Age: 39
Employee Number: 872426
Employee Salary: 36000

KESA PAVAN KUMAR Cell No: 9848461833


77

OOP’s
Part - 4

KESA PAVAN KUMAR Cell No: 9848461833


78

Agenda
1) Abstract Method
2) Abstract class
3) Interface
4) Public,Private and Protected Members
5) str () Method
6) Difference between str() and repr() functions
7) Small Banking Application

Abstract Method:
 Sometimes we don't know about implementation, still we can declare a
method. Such types of methods are called abstract methods.i.e abstract
method has only declaration but not implementation.
 In python we can declare abstract method by using @abstractmethod
decorator as follows.

 @abstractmethod
 def m1(self): pass

 @abstractmethod decorator present in abc module. Hence compulsory


we should import abc module,otherwise we will get error.
 abc  abstract base class module

1) class Test:
2) @abstractmethod
3) def m1(self):
4) pas
s
NameError: name 'abstractmethod' is not defined

Eg:
1) from abc import *
2) class Test:
3) @abstractmethod
4) def m1(self):
5) pass

KESA PAVAN KUMAR Cell No: 9848461833


79

Eg:
1) from abc import *
2) class Fruit:
3) @abstractmethod
4) def taste(self):
5) pass

Child classes are responsible to provide implemention for parent class abstract
methods.

Abstract class:
Some times implementation of a class is not complete,such type of partially
implementation classes are called abstract classes. Every abstract class in
Python should be derived from ABC class which is present in abc module.

Case-1:

1) from abc import *


2) class Test:
3) pass
4)
5) t=Test()

In the above code we can create object for Test class b'z it is concrete class
and it does not conatin any abstract method.

Case-2:

1) from abc import *


2) class Test(ABC):
3) pass
4)
5) t=Test()

In the above code we can create object, even it is derived from ABC
class,b'z it does not contain any abstract method.

Case-3:
1) from abc import *
2) class Test(ABC):
3) @abstractmethod
4) def m1(self):
5) pass

KESA PAVAN KUMAR Cell No: 9848461833


80

6)
7) t=Test()

TypeError: Can't instantiate abstract class Test with abstract methods m1

Case-4:

1) from abc import *


2) class Test:
3)
4) @abstractmeth
def m1(self):
od
5) pas
6) s
7)
t=Test()
We can create object even class contains abstract method b'z we are not
extending ABC class.

Case-5:

1) from abc import *


2) class Test:
3)
4) @abstractmeth
def m1(self):
od
5) print('Hello
6) ')
7)
t=Test()
8) t.m1()

Output: Hello

Conclusion: If a class contains atleast one abstract method and if we are


extending ABC class then instantiation is not possible.

"abstract class with abstract method instantiation is not possible"

Parent class abstract methods should be implemented in the child classes.


Otherwise we cannot instantiate child class.If we are not creating child class
object then we won't get any error.

Case-1:
1) from abc import *
2) class Vehicle(ABC):
3) @abstractmethod

KESA PAVAN KUMAR Cell No: 9848461833


81

KESA PAVAN KUMAR Cell No: 9848461833


82

4) def noofwheels(self):
5) pass
6)
7) class Bus(Vehicle): pass

It is valid because we are not creating Child class object.

Case-2:

1) from abc import *


2) class Vehicle(ABC):
3)
4) @abstractmeth
def noofwheels(self):
od
5) pas
6) s
7) class Bus(Vehicle):
pass
8) b=Bus()

TypeError: Can't instantiate abstract class Bus with abstract methods noofwheels

Note: If we are extending abstract class and does not override its abstract
method then child class is also abstract and instantiation is not possible.

1) from abc import *


2) class Vehicle(ABC):
3)
4) @abstractmeth
def noofwheels(self):
od
5) pas
6) s
7) class
Bus(Vehicle):
8) def noofwheels(self):
9) return
10 7
)11) class
Auto(Vehicle):
12) def noofwheels(self):
13 return
) b=Bus()
14) 3
15)
print(b.noofwheels())#7
16
)
17)
18) a=Auto()
print(a.noofwheels())#3

Note: Abstract class can contain both abstract and non-abstract methods also.

KESA PAVAN KUMAR Cell No: 9848461833


83

Interfaces In Python:
In general if an abstract class contains only abstract methods such type of
abstract class is considered as interface.

1) from abc import *


2) class DBInterface(ABC):
3) @abstractmethod
4) def
connect(self):pass 5)
6) @abstractmethod
7) def
disconnect(self):pass 8)
9) class Oracle(DBInterface):
10) def connect(self):
11) print('Connecting to Oracle Database...')
12) def disconnect(self):
13) print('Disconnecting to Oracle
Database...') 14)
15) class Sybase(DBInterface):
16) def connect(self):
17) print('Connecting to Sybase Database...')
18) def disconnect(self):
19) print('Disconnecting to Sybase
Database...') 20)
21) dbname=input('Enter Database Name:')
22) classname=globals()[dbname]
23) x=classname()
24) x.connect()
25) x.disconnect()

D:\durga_classes>py test.py
Enter Database
Name:Oracle Connecting to
Oracle Database...
Disconnecting to Oracle Database...

D:\durga_classes>py test.py
Enter Database
Name:Sybase Connecting to
Sybase Database...
Disconnecting to Sybase Database...

Note: The inbuilt function globals()[str] converts the string 'str' into a class
name and returns the classname.

KESA PAVAN KUMAR Cell No: 9848461833


84

Demo Program-2: Reading class name from the file

config.txt
EPSON

test.py
1) from abc import *
2) class Printer(ABC):
3) @abstractmethod
4) def
printit(self,text):pass 5)
6) @abstractmethod
7) def
disconnect(self):pass 8)
9) class EPSON(Printer):
10) def printit(self,text):
11) print('Printing from EPSON Printer...')
12) print(text)
13) def disconnect(self):
14) print('Printing completed on EPSON
Printer...') 15)
16) class HP(Printer):
17) def printit(self,text):
18) print('Printing from HP Printer...')
19) print(text)
20) def disconnect(self):
21) print('Printing completed on HP
Printer...') 22)
23) with open('config.txt','r') as f:
24) pname=f.readlin
e() 25)
26) classname=globals()[pname]
27) x=classname()
28) x.printit('This data has to print...')
29) x.disconnect()

Output:
Printing from EPSON
Printer... This data has to
print...
Printing completed on EPSON Printer...

KESA PAVAN KUMAR Cell No: 9848461833


85

Concreate class vs Abstract Class vs Inteface:


1) If we dont know anything about implementation just we have
requirement specification then we should go for interface.
2) If we are talking about implementation but not completely then we
should go for abstract class. (partially implemented class).
3) If we are talking about implementation completely and ready to provide
service then we should go for concrete class.

1) from abc import *


2) class CollegeAutomation(ABC):
3) @abstractmethod
4) def m1(self): pass
5) @abstractmethod
6) def m2(self): pass
7) @abstractmethod
8) def m3(self): pass
9) class AbsCls(CollegeAutomation):
10) def m1(self):
11) print('m1 method implementation')
12) def m2(self):
13) print('m2 method implementation')
14)
15) class ConcreteCls(AbsCls):
16) def m3(self):
17) print('m3 method implemnentation')
18)
19) c=ConcreteCls()
20) c.m1()
21) c.m2()
22) c.m3()

Public, Protected and Private Attributes:


By default every attribute is public. We can access from anywhere either
within the class or from outside of the class.
Eg: name = 'durga'

Protected attributes can be accessed within the class anywhere but from
outside of the class only in child classes. We can specify an attribute as
protected by prefexing with _ symbol.

Syntax: _variablename = value


Eg: _name='durga'

KESA PAVAN KUMAR Cell No: 9848461833


86

But is is just convention and in reality does not exists protected attributes.

private attributes can be accessed only within the class.i.e from outside of the
class we cannot access. We can declare a variable as private explicitly by
prefexing with 2 underscore symbols.

syntax:

variablename=value Eg:

name='durga'

1) class Test:
2) x=10
3) _y=20
4) z=30
5) def m1(self):
6) print(Test.x)
7) print(Test._y)
8) print(Test. z)
9)
10) t=Test()
11) t.m1()
12) print(Test.x)
13) print(Test._y)
14) print(Test. z)

Output:
10
20
30
10
20
Traceback (most recent call last):
File "test.py", line 14, in
<module> print(Test. z)
AttributeError: type object 'Test' has no attribute ' z'

How to Access Private Variables from Outside of the


Class:
We cannot access private variables directly from outside of the class.
But we can access indirectly as follows objectreference._classname variablename

1) class
Test:def init (self):
2)
3) self. x=10
4)
KESA PAVAN KUMAR Cell No: 9848461833
87

5) t=Test()
6) print(t._Test x)#10

str () method:
 Whenever we are printing any object reference internally str () method
will be called which is returns string in the following format
< main .classname object at 0x022144B0>

 To return meaningful string representation we have to override str () method.

1) class Student:
2) def init (self,name,rollno):
3) self.name=name
4) self.rollno=roll
5) no
6) def str (self):
7) return 'This is Student with Name:{} and
Rollno:{}'.format(self.name,self.rollno)
8)
9) s1=Student('Durga',101)
10) s2=Student('Ravi',102)
11) print(s1)
12) print(s2)
Output without Overriding str():
< main .Student object at 0x022144B0>
< main .Student object at 0x022144D0>

Output with Overriding str():


This is Student with Name: Durga and
Rollno: 101 This is Student with Name:
Ravi and Rollno: 102

Difference between str() and


repr() OR
Difference between str () and repr ()
 str() internally calls str () function and hence functionality of both is same.
 Similarly,repr() internally calls repr () function and hence functionality of
both is same.
 str() returns a string containing a nicely printable representation object.
 The main purpose of str() is for readability.It may not possible to convert
result string to original object.

KESA PAVAN KUMAR Cell No: 9848461833


88

1) import datetime
2) today=datetime.datetime.now()
3) s=str(today)#converting datetime object to str
4) print(s)
5) d=eval(s)#converting str object to datetime

D:\durgaclasses>py
test.py 2018-05-18
22:48:19.890888
Traceback (most recent call last):
File "test.py", line 5, in <module>
d=eval(s)#converting str object to
datetime File "<string>", line 1
2018-05-18 22:48:19.890888
^
SyntaxError: invalid token

But repr() returns a string containing a printable representation of object.


The main goal of repr() is unambigouous. We can convert result string to
original object by using eval() function,which may not possible in str()
function.

1) import datetime
2) today=datetime.datetime.now()
3) s=repr(today)#converting datetime object to str
4) print(s)
5) d=eval(s)#converting str object to datetime
6) print(d)

Output:
datetime.datetime(2018, 5, 18, 22, 51, 10, 875838)
2018-05-18 22:51:10.875838

Note: It is recommended to use repr() instead of str()

Mini Project: Banking Application


1) class Account:
2) def init (self,name,balance,min_balance):
3) self.name=name
4) self.balance=balance
5) self.min_balance=min_balance
6)
7) def deposit(self,amount):
8) self.balance +=amount
9)
10) def withdraw(self,amount):

KESA PAVAN KUMAR Cell No: 9848461833


89

11) if self.balance-amount >= self.min_balance:


12) self.balance -=amount
13) else:
14) print("Sorry, Insufficient
Funds") 15)
16) def printStatement(self):
17) print("Account
Balance:",self.balance) 18)
19) class Current(Account):
20) def init (self,name,balance):
21) super(). init (name,balance,min_balance=-1000)
22) def str (self):
23) return "{}'s Current Account with Balance
:{}".format(self.name,self.balance) 24)
25) class Savings(Account):
26) def init (self,name,balance):
27) super(). init (name,balance,min_balance=0)
28) def str (self):
29) return "{}'s Savings Account with Balance
:{}".format(self.name,self.balance) 30)
31) c=Savings("Durga",10000)
32) print(c)
33) c.deposit(5000)
34) c.printStatement()
35) c.withdraw(16000)
36) c.withdraw(15000)
37) print(c
) 38)
39) c2=Current('Ravi',20000)
40) c2.deposit(6000)
41) print(c2)
42) c2.withdraw(27000)
43) print(c2)

Output:
D:\durgaclasses>py test.py
Durga's Savings Account with Balance
:10000 Account Balance: 15000
Sorry, Insufficient Funds
Durga's Savings Account with
Balance :0 Ravi's Current Account
with Balance :26000 Ravi's Current
Account with Balance :-1000

KESA PAVAN KUMAR Cell No: 9848461833


90

EXCEPTION
HANDLING

KESA PAVAN KUMAR Cell No: 9848461833


91

In any programming language there are 2 types of errors are possible.

1) Syntax Errors
2) Runtime Errors

1)Syntax Errors:
The errors which occur because of invalid syntax are called syntax errors.

Eg 1:
x = 10
if x == 10
print("Hello
")

SyntaxError: invalid syntax

Eg 2:
print "Hello"
SyntaxError: Missing parentheses in call to 'print'

Note: Programmer is responsible to correct these syntax errors. Once all


syntax errors are corrected then only program execution will be started.

2)Runtime Errors:
 Also known as exceptions.
 While executing the program if something goes wrong because of end
user input or programming logic or memory problems etc then we will
get Runtime Errors.

Eg:
1) print(10/0)  ZeroDivisionError: division by zero
2) print(10/"ten")  TypeError: unsupported operand type(s) for /: 'int' and 'str'

3) x = int(input("Enter
Number:")) print(x)

D:\Python_classes>py
test.py Enter Number:ten
ValueError: invalid literal for int() with base 10: 'ten'

Note: Exception Handling concept applicable for Runtime Errors but not for syntax
errors

KESA PAVAN KUMAR Cell No: 9848461833


92

What is Exception?
An unwanted and unexpected event that disturbs normal flow of program is
called exception.

Eg:
 ZeroDivisionError
 TypeError
 ValueError
 FileNotFoundError
 EOFError
 SleepingError
 TyrePuncturedError

It is highly recommended to handle exceptions. The main objective of


exception handling is Graceful Termination of the program (i.e we should not
block our resources and we should not miss anything)

Exception handling does not mean repairing exception. We have to define


alternative way to continue rest of the program normally.

Eg: For example our programming requirement is reading data from remote
file locating at London. At runtime if London file is not available then the
program should not be terminated abnormally. We have to provide local file
to continue rest of the program normally. This way of defining alternative is
nothing but exception handling.

try:
Read Data from Remote File locating at
London. except FileNotFoundError:
use local file and continue rest of the program normally

Q. What is an Exception?
Q. What is the purpose of Exception Handling?
Q. What is the meaning of Exception Handling?

Default Exception Handing in Python:


 Every exception in Python is an object. For every exception type the
corresponding classes are available.
 Whevever an exception occurs PVM will create the corresponding
exception object and will check for handling code. If handling code is
not available then Python interpreter terminates the program abnormally
and prints corresponding exception information to the console.
 The rest of the program won't be executed.

KESA PAVAN KUMAR Cell No: 9848461833


93

1) print("Hello")
2) print(10/0)
3) print("Hi")

D:\Python_classes>py
test.py Hello
Traceback (most recent call last):
File "test.py", line 2, in
<module> print(10/0)
ZeroDivisionError: division by zero

Python's Exception
Hierarchy
BaseExceptio
n

Exceptio SystemExi GeneratorExit KeyboardInterru


n t pt

Attribut Arithmetic EOF Name Lookup OS Type Valu


e e
Error Error Error Error Error Error Error Error

ZeroDivisi Index FileNotFou


on Error nd Error
Error
FloatingPoi Key Interrupte
nt Erro d Error
Error r
Overflo
w Permissi
Error on
Error

TimeO
ut
 Every Exception in Python is a Error
class.
 All exception classes are child classes of BaseException.i.e every
exception class extends BaseException either directly or indirectly.
KESA PAVAN KUMAR Cell No: 9848461833
94

Hence BaseException acts as root for Python Exception Hierarchy.


 Most of the times being a programmer we have to concentrate Exception
and its child classes.

KESA PAVAN KUMAR Cell No: 9848461833


95

Customized Exception Handling by using try-


except:
 It is highly recommended to handle exceptions.
 The code which may raise exception is called risky code and we have to
take risky code inside try block. The corresponding handling code we have
to take inside except block.
try:
Risky
Code except
XXX:
Handling code/Alternative Code

Without try-except:
1) print("stmt-1")
2) print(10/0)
3) print("stmt-3")

Output
stmt-1
ZeroDivisionError: division by zero
Abnormal termination/Non-Graceful Termination

With try-except:
1) print("stmt-1")
2) try:
3) print(10/0)
4) except ZeroDivisionError:
5) print(10/2)
6) print("stmt-3")

Outpu
t stmt-1
5.0
stmt-3
Normal termination/Graceful Termination

Control Flow in try-except:


try:
stmt-
1
stmt-
2
stmt-
3
except XXX:
KESA PAVAN KUMAR Cell No: 9848461833
96

stmt-
4 stmt-5

KESA PAVAN KUMAR Cell No: 9848461833


97

Case-1: If there is no exception


1,2,3,5 and Normal Termination

Case-2: If an exception raised at stmt-2 and corresponding except block


matched 1,4,5 Normal Termination

Case-3: If an exception rose at stmt-2 and corresponding except block


not matched 1, Abnormal Termination

Case-4: If an exception rose at stmt-4 or at stmt-5 then it is always abnormal


termination.

Conclusions:
1) Within the try block if anywhere exception raised then rest of the try
block won’t be executed eventhough we handled that exception. Hence
we have to take only risky code inside try block and length of the try
block should be as less as possible.
2) In addition to try block, there may be a chance of raising exceptions inside
except and finally blocks also.
3) If any statement which is not part of try block raises an exception then
it is always abnormal termination.

How to Print Exception Information:


try:

1) print(10/0)
2) except ZeroDivisionError as msg:
3) print("exception raised and its description is:",msg)

Output exception raised and its description is: division by zero

try with Multiple except Blocks:


The way of handling exception is varied from exception to exception.Hence
for every exception type a seperate except block we have to provide. i.e try
with multiple except blocks is possible and recommended to use.

Eg:
try:
-------
-------
-------
except ZeroDivisionError:
perform alternative arithmetic operations

KESA PAVAN KUMAR Cell No: 9848461833


98

except FileNotFoundError:
use local file instead of remote file

If try with multiple except blocks available then based on raised


exception the corresponding except block will be executed.

1) try:
2) x=int(input("Enter First Number: "))
3) y=int(input("Enter Second Number: "))
4) print(x/y)
5) except ZeroDivisionError :
6) print("Can't Divide with Zero")
7) except ValueError:
8) print("please provide int value only")

D:\Python_classes>py
test.py Enter First
Number: 10
Enter Second
Number: 2 5.0

D:\Python_classes>py
test.py Enter First
Number: 10
Enter Second
Number: 0 Can't
Divide with Zero

D:\Python_classes>py
test.py Enter First
Number: 10
Enter Second Number:
ten please provide int
value only

If try with multiple except blocks available then the order of these except
blocks is important .Python interpreter will always consider from top to
bottom until matched except block identified.

1) try:
2) x=int(input("Enter First Number: "))
3) y=int(input("Enter Second Number: "))
4) print(x/y)
5) except ArithmeticError :
6) print("ArithmeticError")
7) except ZeroDivisionError:
8) print("ZeroDivisionError")

D:\Python_classes>py
test.py Enter First
KESA PAVAN KUMAR Cell No: 9848461833
99

Number: 10

KESA PAVAN KUMAR Cell No: 9848461833


100

Enter Second
Number: 0
ArithmeticError

Single except Block that can handle Multiple Exceptions:


We can write a single except block that can handle multiple different types of
exceptions.

except (Exception1,Exception2,exception3,..):
OR
except (Exception1,Exception2,exception3,..)
as msg :

Parentheses are mandatory and this group of exceptions internally considered as


tuple.

1) try:
2) x=int(input("Enter First Number: "))
3) y=int(input("Enter Second Number: "))
4) print(x/y)
5) except (ZeroDivisionError,ValueError) as msg:
6) print("Plz Provide valid numbers only and problem is: ",msg)

D:\Python_classes>py
test.py Enter First
Number: 10
Enter Second Number: 0
Plz Provide valid numbers only and problem is: division by zero

D:\Python_classes>py
test.py Enter First
Number: 10
Enter Second Number: ten
Plz Provide valid numbers only and problem is: invalid literal for int() with b are 10: 'ten'

Default except Block:


We can use default except block to handle any type of exceptions.
In default except block generally we can print normal error messages.

Syntax:
excep
t:
statements

1) try:
2) x=int(input("Enter First Number: "))
3) y=int(input("Enter Second Number: "))
4) print(x/y)
5) except ZeroDivisionError:
KESA PAVAN KUMAR Cell No: 9848461833
101

6) print("ZeroDivisionError:Can't divide with zero")


7) except:
8) print("Default Except:Plz provide valid input only")

KESA PAVAN KUMAR Cell No: 9848461833


102

D:\Python_classes>py
test.py Enter First
Number: 10
Enter Second Number: 0
ZeroDivisionError:Can't divide
with zero

D:\Python_classes>py
test.py Enter First
Number: 10
Enter Second Number: ten
Default Except:Plz provide valid input only

***Note: If try with multiple except blocks available then default except block
should be last, otherwise we will get SyntaxError.

1) try:
2) print(10/0)
3) except:
4) print("Default Except")
5) except ZeroDivisionError:
6) print("ZeroDivisionError")

SyntaxError: default 'except:' must be last

Note: The following are various possible combinations of except blocks


1) except ZeroDivisionError:
2) except ZeroDivisionError as msg:
3) except (ZeroDivisionError,ValueError) :
4) except (ZeroDivisionError,ValueError) as msg:
5) except :

finally Block:
☕ It is not recommended to maintain clean up code(Resource
Deallocating Code or Resource Releasing code) inside try block
because there is no guarentee for the execution of every statement
inside try block always.
☕ It is not recommended to maintain clean up code inside except block,
because if there is no exception then except block won't be executed.
☕ Hence we required some place to maintain clean up code which should be
executed always irrespective of whether exception raised or not raised
and whether exception handled or not handled. Such type of best place is
nothing but finally block.
☕ Hence the main purpose of finally block is to maintain clean up code.

try:
Risky Code
except:
Handling Code
KESA PAVAN KUMAR Cell No: 9848461833
103

finally:
Cleanup code

The speciality of finally block is it will be executed always whether exception


raised or not raised and whether exception handled or not handled.

Case-1: If there is no exception


1) try:
2) print("try")
3) except:
4) print("except")
5) finally:
6) print("finally")

Outpu
t try
finally

Case-2: If there is an exception raised but handled


1) try:
2) print("try")
3) print(10/0)
4) except ZeroDivisionError:
5) print("except")
6) finally:
7) print("finally")

Outpu
t try
except
finally

Case-3: If there is an exception raised but not handled


1) try:
2) print("try")
3) print(10/0)
4) except NameError:
5) print("except")
6) finally:
7) print("finally")

KESA PAVAN KUMAR Cell No: 9848461833


104

Outpu
t try
finally
ZeroDivisionError: division by zero(Abnormal Termination)

*** Note: There is only one situation where finally block won't be executed ie
whenever we are using os._exit(0) function.

Whenever we are using os._exit(0) function then Python Virtual Machine


itself will be shutdown.In this particular case finally won't be executed.

1) imports
2) try:
3) print("try")
4) os._exit(0)
5) except NameError:
6) print("except")
7) finally:
8) print("finally")

Output: try

Note:
os._exit(0)
Where 0 represents status code and it indicates normal
termination There are multiple status codes are possible.

Control Flow in try-except-finally:


try:
stmt-
1
stmt-
2
stmt-
3
except:
stmt-4
finally:
stmt-
5
stmt-
6

Case-1: If there is no
exception 1,2,3,5,6 Normal
Termination

Case-2: If an exception raised at stmt2 and the corresponding except


KESA PAVAN KUMAR Cell No: 9848461833
105

block matched 1,4,5,6 Normal Termination

KESA PAVAN KUMAR Cell No: 9848461833


106

Case-3: If an exception raised at stmt2 but the corresponding except block


not matched 1,5 Abnormal Termination

Case-4:If an exception raised at stmt4 then it is always abnormal termination


but before that finally block will be executed.

Case-5: If an exception raised at stmt-5 or at stmt-6 then it is always


abnormal termination

Nested try-except-finally Blocks:


We can take try-except-finally blocks inside try or except or finally blocks.i.e
nesting of try- except-finally is possible.
try:
---------
-
---------
-
--------- -------------
- --------------
try: --------------

--------------
--------------
excep --------------
t: ------------
except:
-----------
-----------
-----------

General Risky code we have to take inside outer try block and too much risky
code we have to take inside inner try block. Inside Inner try block if an
exception raised then inner except block is responsible to handle. If it is
unable to handle then outer except block is responsible to handle.

1) try:
2) print("outer try block")
3)
4) tryprint("Inner try
:5) block")
print(10/0
6) )
except ZeroDivisionError:
7) print("Inner except
8) block")
finally:
9) print("Inner finally
block")

KESA PAVAN KUMAR Cell No: 9848461833


107

10) except:
11) print("outer except block")
12) finally:
13) print("outer finally block")

Output
outer try
block Inner
try block
Inner except
block Inner
finally block
outer finally
block

Control Flow in nested try-except-finally:


try:
stmt-
1
stmt-
2
stmt-
3 try:
stmt-
4
stmt-
5
stmt-
6
except X:
stmt-7
finally:
stmt-
8
except Y: stmt-
stmt- 9
10
finally:
stmt-
11
stmt-
12

Case-1: If there is no exception


1,2,3,4,5,6,8,9,11,12 Normal
Termination

Case-2: If an exception raised at stmt-2 and the corresponding except block


matched 1,10,11,12 Normal Termination
KESA PAVAN KUMAR Cell No: 9848461833
108

Case-3: If an exceptiion raised at stmt-2 and the corresponding except block not
matched 1,11,Abnormal Termination

Case-4: If an exception raised at stmt-5 and inner except block matched


1,2,3,4,7,8,9,11,12 Normal Termination

KESA PAVAN KUMAR Cell No: 9848461833


109

Case-5: If an exception raised at stmt-5 and inner except block not


matched but outer except block matched 1,2,3,4,8,10,11,12,Normal
Termination

Case-6:If an exception raised at stmt-5 and both inner and outer except
blocks are not matched 1,2,3,4,8,11,Abnormal Termination

Case-7: If an exception raised at stmt-7 and corresponding except block matched


1,2,3,.,.,.,8,10,11,12,Normal Termination

Case-8: If an exception raised at stmt-7 and corresponding except block not matched
1,2,3,.,.,.,8,11,Abnormal Termination

Case-9: If an exception raised at stmt-8 and corresponding except block matched


1,2,3,.,.,.,.,10,11,12 Normal Termination

Case-10: If an exception raised at stmt-8 and corresponding except block not


matched 1,2,3,.,.,.,.,11,Abnormal Termination

Case-11: If an exception raised at stmt-9 and corresponding except block matched


1,2,3,.,.,.,.,8,10,11,12,Normal Termination

Case-12: If an exception raised at stmt-9 and corresponding except block not


matched 1,2,3,.,.,.,.,8,11,Abnormal Termination

Case-13: If an exception raised at stmt-10 then it is always abonormal


termination but before abnormal termination finally block(stmt-11) will be
executed.

Case-14: If an exception raised at stmt-11 or stmt-12 then it is always


abnormal termination.

Note: If the control entered into try block then compulsary finally block will be
executed. If the control not entered into try block then finally block won't be
executed.

else Block with try-except-finally:


We can use else block with try-except-finally blocks.
else block will be executed if and only if there are no exceptions inside try block.

try:
Risky Code
except:
will be executed if exception inside try

KESA PAVAN KUMAR Cell No: 9848461833


110

else:
will be executed if there is no exception inside try
finally
will be executed whether exception raised or not raised and handled or not
:

handled

E
g:
try print("try")
: print(10/0) 
1
except:
print("except")
else:
print("else")
finally
print("finally
:
")

If we comment line-1 then else block will be executed b'z there is no


exception inside try. In this case the output is:
try
else
finall
y

If we are not commenting line-1 then else block won't be executed b'z there is
exception inside try block. In this case output is:
try
excep
t
finall
y

Various possible Combinations of try-except-else-finally:


1) Whenever we are writing try block, compulsory we should write
except or finally block.i.e without except or finally block we cannot
write try block.
2) Wheneever we are writing except block, compulsory we should write
try block. i.e except without try is always invalid.
3) Whenever we are writing finally block, compulsory we should write try
block. i.e finally without try is always invalid.
4) We can write multiple except blocks for the same try,but we cannot
write multiple finally blocks for the same try
5) Whenever we are writing else block compulsory except block should
be there. i.e without except we cannot write else block.
6) In try-except-else-finally order is important.
KESA PAVAN KUMAR Cell No: 9848461833
111

7) We can define try-except-else-finally inside try, except, else and finally


blocks. i.e nesting of try-except-else-finally is always possible.

KESA PAVAN KUMAR Cell No: 9848461833


112

try:
1
print("try") 
except:
2
print("Hello") 
else:
3
print("Hello") 
finally:
4
print("Hello") 
try:
print("try"
5
) except: √
print("except")
try:
print("try")
6
finally: √
print("finally")
try:
print("try"
) except:
7
print("except") √
else:
print("else")
try:
print("try")
8
else: 
print("else")
try:
print("try")
else:
9
print("else") 
finally:
print("finally")
try:
print("try"
) except XXX:
10
print("except-1") √
except YYY:
print("except-2")
try:
print("try")
11
except : 
print("except-1")

KESA PAVAN KUMAR Cell No: 9848461833


113

else:
print("else")
else:
print("else")
try:
print("try"
) except :
print("except-1")
12
finally: 
print("finally")
finally:
print("finally")
try:
print("try"
13 ) print("Hello") 
except:
print("except")
try:
print("try"
) except:
14 print("except
") print("Hello")

except:
print("except")
try:
print("try"
) except:
15 print("except
") print("Hello")

finally:
print("finally")
try:
print("try"
) except:
16 print("except
") print("Hello")

else:
print("else")
try:
print("try"
) except:
17
print("except") √
try:
print("try")

KESA PAVAN KUMAR Cell No: 9848461833


114

except:
print("except")
try:
print("try"
) except:
print("except")
18
try: √
print("try")
finally:
print("finally")
try:
print("try"
) except:
print("except
19
") if 10>20: √
print("if")
else:
print("else")
try:
print("try"
) try:
print("inner
try") except:
20
print("inner except √
block") finally:
print("inner finally
block")
except:
print("except")
try:
print("try")

except:
print("except
21 ") try:
print("inner

try") except:
print("inner except
block") finally:
print("inner finally
block")
try:
print("try"
22 ) except:
print("except")

finally:

KESA PAVAN KUMAR Cell No: 9848461833


115

try:
print("inner
try") except:
print("inner except
block") finally:
print("inner finally
block")
try:
print("try"
) except:
23
try:
print("except")

print("try")
else:
print("else")
try:
print("try"
) try:
24
print("inner try") 
except:
print("except")
try:
print("try")
else:
print("else
25
") except: 
print("except")
finally:
print("finally")

Types of Exceptions:
In Python there are 2 types of exceptions are possible.
1) Predefined Exceptions
2) User Definded Exceptions

1)Predefined Exceptions:
 Also known as inbuilt exceptions.
 The exceptions which are raised automatically by Python virtual machine
whenver a particular event occurs are called pre defined exceptions.

Eg 1: Whenever we are trying to perform Division by zero, automatically


Python will raise ZeroDivisionError.
print(10/0)

KESA PAVAN KUMAR Cell No: 9848461833


116

Eg 2: Whenever we are trying to convert input value to int type and if input
value is not int value then Python will raise ValueError automatically
x=int("ten")  ValueError

2)User Defined Exceptions:


 Also known as Customized Exceptions or Programatic Exceptions
 Some time we have to define and raise exceptions explicitly to indicate that
something goes wrong, such type of exceptions are called User Defined
Exceptions or Customized Exceptions
 Programmer is responsible to define these exceptions and Python not
having any idea about these. Hence we have to raise explicitly based on
our requirement by using "raise" keyword.
Eg:
 InSufficientFundsException
 InvalidInputException
 TooYoungException
 TooOldException

How to Define and Raise Customized Exceptions:


Every exception in Python is a class that extends Exception class either
directly or indirectly.

Syntax:
class classname(predefined exception class
name): def init (self,arg):
self.msg=arg

1) class TooYoungException(Exception):
2) def init (self,arg):
3) self.msg=arg

TooYoungException is our class name which is the child class of Exception

We can raise exception by using raise keyword as


follows raise TooYoungException("message")

1) class
TooYoungException(Exception):
2) def init (self,arg):
3) self.msg=a
4) rg
5) class
TooOldException(Exception):
6) def init (self,arg):
7) self.msg=a
8) rg

KESA PAVAN KUMAR Cell No: 9848461833


117

9) age=int(input("Enter Age:"))
10) if age>60:
11) raise TooYoungException("Plz wait some more time you will get best match
soon!!!")
12) elif age<18:
13) raise TooOldException("Your age already crossed marriage age...no chance of
getting marriage")
14) else:
15) print("You will get match details soon by email!!!")

D:\Python_classes>py
test.py Enter Age:90
main .TooYoungException: Plz wait some more time you will get best match soon!!!

D:\Python_classes>py
test.py Enter Age:12
main .TooOldException: Your age already crossed marriage age...no
chance of g etting marriage

D:\Python_classes>py
test.py Enter Age:27
You will get match details soon by email!!!

Note: raise keyword is best suitable for customized exceptions but not for
pre defined exceptions

KESA PAVAN KUMAR Cell No: 9848461833


118

FILE
HANDLING

KESA PAVAN KUMAR Cell No: 9848461833


119

 As the part of programming requirement, we have to store our data


permanently for future purpose. For this requirement we should go for
files.
 Files are very common permanent storage areas to store our data.

Types of Files:
There are 2 types of files

1) Text Files:
Usually we can use text files to store
character data Eg: abc.txt

2) Binary Files:
Usually we can use binary files to store binary data like images,video files,
audio files etc...

Opening a File:
 Before performing any operation (like read or write) on the file,first we
have to open that file.For this we should use Python's inbuilt function
open()
 But at the time of open, we have to specify mode,which represents the
purpose of opening file.
f = open(filename, mode)
The allowed modes in Python are

1) r  open an existing file for read operation. The file pointer is


positioned at the beginning of the file.If the specified file does not exist
then we will get FileNotFoundError.This is default mode.

2) w  open an existing file for write operation. If the file already contains
some data then it will be overridden. If the specified file is not already
avaialble then this mode will create that file.

3) a  open an existing file for append operation. It won't override existing


data. If the specified file is not already available then this mode will create a
new file.

4) r+  To read and write data into the file. The previous data in the file
will not be deleted.The file pointer is placed at the beginning of the file.
5) w+  To write and read data. It will override existing data.

6) a+  To append and read data from the file.It wont override existing data.

7) x  To open a file in exclusive creation mode for write operation. If the


file already exists then we will get FileExistsError.

KESA PAVAN KUMAR Cell No: 9848461833


120

Note: All the above modes are applicable for text files. If the above modes
suffixed with 'b' then these represents for binary files.

Eg: rb,wb,ab,r+b,w+b,a+b,xb

f = open("abc.txt","w")
We are opening abc.txt file for writing data.

Closing a File:
After completing our operations on the file, it is highly recommended to
close the file. For this we have to use close() function.
f.c lose()

Various Properties of File Object:


Once we opend a file and we got file object, we can get various details related
to that file by using its properties.
 name  Name of opened file
 mode  Mode in which the file is opened
 closed  Returns boolean value indicates that file is closed or not
 readable() Retruns boolean value indicates that whether file is readable or not
 writable() Returns boolean value indicates that whether file is writable or not.

1) f=open("abc.txt",'w')
2) print("File Name: ",f.name)
3) print("File Mode: ",f.mode)
4) print("Is File Readable: ",f.readable())
5) print("Is File Writable: ",f.writable())
6) print("Is File Closed : ",f.closed)
7) f.close()
8) print("Is File Closed : ",f.closed)

Output
D:\Python_classes>py
test.py File Name: abc.txt
File Mode: w
Is File Readable:
False Is File
Writable: True Is
File Closed: False
Is File Closed: True

KESA PAVAN KUMAR Cell No: 9848461833


121

Writing Data to Text Files:


We can write character data to the text files by using the following 2 methods.
1) write(str)
2) writelines(list of lines)

1) f=open("abcd.txt",'w')
2) f.write("Durga\n")
3) f.write("Software\n")
4) f.write("Solutions\n")
5) print("Data written to the file successfully")
6) f.close()

abcd.txt:
Durga
Softwar
e
Solutio
ns

Note: In the above program, data present in the file will be overridden
everytime if we run the program. Instead of overriding if we want append
operation then we should open the file as follows.

f = open("abcd.txt","a")
Eg 2:

1) f=open("abcd.txt",'w')
2) list=["sunny\n","bunny\n","vinny\n","chinny"]
3) f.writelines(list)
4) print("List of lines written to the file successfully")
5) f.close()

abcd.txt:
sunn
y
bunn
y
vinny
chinn
y

Note: While writing data by using write() methods, compulsory we have to provide line
seperator(\n), otherwise total data should be written to a single line.

KESA PAVAN KUMAR Cell No: 9848461833


122

Reading Character Data from Text Files:


We can read character data from text file by using the following read methods.

 read() To read total data from the file


 read(n)  To read 'n' characters from the file
 readline() To read only one line
 readlines() To read all lines into a list

Eg 1: To read total data from the file


1) f=open("abc.txt",'r')
2) data=f.read()
3) print(data)
4) f.close()

Outpu
t sunny
bunny
chinny
vinny

Eg 2: To read only first 10 characters:


1) f=open("abc.txt",'r')
2) data=f.read(10)
3) print(data)
4) f.close()

Outpu
t sunny
bunn

Eg 3: To read data line by line:


1) f=open("abc.txt",'r')
2) line1=f.readline()
3) print(line1,end='')
4) line2=f.readline()
5) print(line2,end='')
6) line3=f.readline()
7) print(line3,end='')
8) f.close()

KESA PAVAN KUMAR Cell No: 9848461833


123

Outpu
t sunny
bunny
chinny

Eg 4: To read all lines into list:


1) f=open("abc.txt",'r')
2) lines=f.readlines()
3) for line in lines:
4) print(line,end='')
5) f.close()

Outpu
t sunny
bunny
chinny
vinny

Eg 5:
1) f=open("abc.txt","r")
2) print(f.read(3))
3) print(f.readline())
4) print(f.read(4))
5) print("Remaining data")
6) print(f.read())

Output
su
n
ny

bunn
Remaining
data y
chinn
y
vinny

The with Statement:


 The with statement can be used while opening a file.We can use this to
group file operation statements within a block.
 The advantage of with statement is it will take care closing of file,after
completing all operations automatically even in the case of exceptions
also, and we are not required to close explicitly.

KESA PAVAN KUMAR Cell No: 9848461833


124

1) with open("abc.txt","w") as f:
2) f.write("Durga\n")
3) f.write("Software\n")
4) f.write("Solutions\n")
5) print("Is File Closed: ",f.closed)
6) print("Is File Closed: ",f.closed)

Output
Is File Closed:
False Is File
Closed: True

The seek() and tell() Methods:


tell():
 We can use tell() method to return current position of the cursor(file
pointer) from beginning of the file. [ can you plese telll current cursor
position]
 The position(index) of first character in files is zero just like string index.

1) f=open("abc.txt","r")
2) print(f.tell())
3) print(f.read(2))
4) print(f.tell())
5) print(f.read(3))
6) print(f.tell())

abc.txt:
sunn
y
bunn
y
chinn
y
vinny

Output:
0
s
u
2
nn
y5

seek():
We can use seek() method to move cursor (file pointer) to
specified location. [Can you please seek the cursor to a particular
KESA PAVAN KUMAR Cell No: 9848461833
125

location]
f.seek(offset, fromwhere)  offset represents the number of positions

KESA PAVAN KUMAR Cell No: 9848461833


126

The allowed Values for 2nd Attribute (from


where) are 0  From beginning of File (Default
Value)
1  From Current
Position 2  From end
of the File

Note: Python 2 supports all 3 values but Python 3 supports only zero.
1) data="All Students are STUPIDS"
2) f=open("abc.txt","w")
3) f.write(data)
4) with open("abc.txt","r+") as f:
5) text=f.read()
6) print(text)
7) print("The Current Cursor Position: ",f.tell())
8) f.seek(17)
9) print("The Current Cursor Position: ",f.tell())
10) f.write("GEMS!!!")
11) f.seek(0)
12) text=f.read()
13) print("Data After Modification:")
14) print(text)

Output
All Students are STUPIDS
The Current Cursor
Position: 24 The Current
Cursor Position: 17 Data
After Modification:
All Students are GEMS!!!

How to check a particular File exists OR not?


We can use os library to get information about files in our computer.
os module has path sub module,which contains isFile() function to
check whether a particular file exists or not?
os.path.isfile(fname)

Q) Write a Program to check whether the given File exists OR


not. If it is available then print its content?
1) import os,sys
2) fname=input("Enter File Name: ")
3) if os.path.isfile(fname):
4) print("File exists:",fname)
5) f=open(fname,"r")
6) else:

KESA PAVAN KUMAR Cell No: 9848461833


127

7) print("File does not exist:",fname)


8) sys.exit(0)
9) print("The content of file is:")
10) data=f.read()
11) print(data)

Output
D:\Python_classes>py
test.py Enter File Name:
durga.txt File does not
exist: durga.txt
D:\Python_classes>py
test.py Enter File Name:
abc.txt
File exists: abc.txt
The content of file
is:
All Students are
GEMS!!! All Students
are GEMS!!! All
Students are
GEMS!!! All Students
are GEMS!!! All
Students are
GEMS!!! All Students
are GEMS!!!

Note:
sys.exit(0)  To exit system without executing rest of the program.
argument represents status code. 0 means normal termination and it is the default
value.

Q) Program to print the Number of Lines, Words and


Characters present in the given File?
1) import os,sys
2) fname=input("Enter File Name: ")
3) if os.path.isfile(fname):
4) print("File exists:",fname)
5) f=open(fname,"r")
6) else:
7) print("File does not exist:",fname)
8) sys.exit(0)
9) lcount=wcount=ccount=0
10) for line in f:
11) lcount=lcount+1
12) ccount=ccount+len(line)
13) words=line.split()
14)KESAwcount=wcount+len(words)
PAVAN KUMAR Cell No: 9848461833
128

15) print("The number of Lines:",lcount)


16) print("The number of Words:",wcount)

KESA PAVAN KUMAR Cell No: 9848461833


129

17) print("The number of Characters:",ccount)

Output
D:\Python_classes>py
test.py Enter File Name:
durga.txt File does not
exist: durga.txt

D:\Python_classes>py
test.py Enter File Name:
abc.txt
File exists: abc.txt
The number of Lines:
6 The number of
Words: 24
The number of Characters: 149

abc.txt
All Students are
GEMS!!! All Students
are GEMS!!! All
Students are
GEMS!!! All Students
are GEMS!!! All
Students are
GEMS!!! All Students
are GEMS!!!

Handling Binary Data:


It is very common requirement to read or write binary data like images,video
files,audio files etc.

Q) Program to read Image File and write to a New Image File?

1) f1=open("rossum.jpg","rb")
2) f2=open("newpic.jpg","wb")
3) bytes=f1.read()
4) f2.write(bytes)
5) print("New Image is available with the name: newpic.jpg")

Handling CSV Files:


⚽ CSV  Comma seperated values
⚽ As the part of programming, it is very common requirement to write and
read data wrt csv files. Python provides csv module to handle csv files.

KESA PAVAN KUMAR Cell No: 9848461833


130

Writing Data to CSV File:


1) import csv
2) with open("emp.csv","w",newline='') as f:
3) w=csv.writer(f) # returns csv writer object
4) w.writerow(["ENO","ENAME","ESAL","EADDR"])
5) n=int(input("Enter Number of Employees:"))
6) for i in range(n):
7) eno=input("Enter Employee No:")
8) ename=input("Enter Employee Name:")
9) esal=input("Enter Employee Salary:")
10 eaddr=input("Enter Employee Address:")
)
11 w.writerow([eno,ename,esal,eaddr])
)
12) print("Total Employees data written to csv file successfully")

Note: Observe the difference with newline attribute and


without with open("emp.csv","w",newline='') as
f:
with open("emp.csv","w") as f:

Note: If we are not using newline attribute then in the csv file blank lines will
be included between data. To prevent these blank lines, newline attribute is
required in Python-3,but in Python-2 just we can specify mode as 'wb' and we
are not required to use newline attribute.

Reading Data from CSV File:


1) import csv
2) f=open("emp.csv",'r')
3) r=csv.reader(f) #returns csv reader object
4) data=list(r)
5) #print(data)
6) for line in data:
7) for word in line:
8) print(word,"\t",end=
9) print()
'')

Output
D:\Python_classes>py test.py

EN ENAM ESA EADD


O E L R
100 Durga 1000 Hyd
200 Sachin 2000Mumba
i
300 Dhoni 3000 Ranchi
KESA PAVAN KUMAR Cell No: 9848461833
131

Zipping and Unzipping Files:


It is very common requirement to zip and unzip files.

The main advantages are:


1) To improve memory utilization
2) We can reduce transport time
3) We can improve performance.

To perform zip and unzip operations, Python contains one in-bulit


module zip file. This module contains a class: ZipFile

To Create Zip File:


We have to create ZipFile class object with name of the zip file, mode
and constant ZIP_DEFLATED. This constant represents we are creating
zip file.
f = ZipFile("files.zip","w","ZIP_DEFLATED")
Once we create ZipFile object,we can add files by using write() method.
f.write(filename)
1) from zipfile import *
2) f=ZipFile("files.zip",'w',ZIP_DEFLATED)
3) f.write("file1.txt")
4) f.write("file2.txt")
5) f.write("file3.txt")
6) f.close()
7) print("files.zip file created successfully")

To perform unzip Operation:


We have to create ZipFile object as follows
f = ZipFile("files.zip","r",ZIP_STORED)

ZIP_STORED represents unzip operation. This is default value and hence we


are not required to specify.
Once we created ZipFile object for unzip operation, we can get all file
names present in that zip file by using namelist() method.
names = f.namelist()
1) from zipfile import *
2) f=ZipFile("files.zip",'r',ZIP_STORED)
3) names=f.namelist()
4) for name in names:
5) print( "File Name: ",name)

KESA PAVAN KUMAR Cell No: 9848461833


132

6) print("The Content of file is:")


this
7) f1=open(name,'r')
8) print(f1.read())
9) print()

Working with Directories:


It is very common requirement to perform operations for directories like
1) To know current working directory
2) To create a new directory
3) To remove an existing directory
4) To rename a directory
5) To list contents of the
directory etc...
To perform these operations, Python provides inbuilt module os,which
contains several functions to perform directory related operations.

Q1) To Know Current Working Directory


import os
cwd = os.getcwd()
print("Current Working Directory:",cwd)

Q2) To Create a Sub Directory in the Current Working Directory


import os
os.mkdir("mysu
b")
print("mysub directory created in cwd")

Q3) To Create a Sub Directory in mysub Directory


cwd
|-mysub
|-mysub2

import os
os.mkdir("mysub/mysu
b2")
print("mysub2 created inside mysub")

Note: Assume mysub already present in cwd.

Q4) To Create Multiple Directories like sub1 in that


sub2 in that sub3
import os
os.makedirs("sub1/sub2/su
b3")
print("sub1 and in that sub2 and in that sub3 directories created")

KESA PAVAN KUMAR Cell No: 9848461833


133

Q5) To Remove a Directory


import os
os.rmdir("mysub/mysub2")
print("mysub2 directory
deleted")

Q6) To Remove Multiple Directories in the Path


import os
os.removedirs("sub1/sub2/su
b3")
print("All 3 directories sub1,sub2 and sub3 removed")

Q7) To Rename a Directory


import os
os.rename("mysub","new
dir")
print("mysub directory renamed to newdir")

Q8) To know Contents of Directory


OS Module provides listdir() to list out the contents of the specified
directory. It won't display the contents of sub directory.

1) import os
2) print(os.listdir("."))

Output
D:\Python_classes>py test.py
['abc.py', 'abc.txt', 'abcd.txt', 'com', 'demo.py', 'durgamath.py', 'emp.csv', '
file1.txt', 'file2.txt', 'file3.txt', 'files.zip', 'log.txt', 'module1.py', 'myl
og.txt', 'newdir', 'newpic.jpg', 'pack1', 'rossum.jpg', 'test.py', ' pycache ']

 The above program display contents of current working directory but not
contents of sub directories.
 If we want the contents of a directory including sub directories then we
should go for walk() function.

Q9) To Know Contents of Directory including Sub


Directories
 We have to use walk() function
 [Can you please walk in the directory so that we can aware all
contents of that directory]
 os.walk(path, topdown = True, onerror = None, followlinks = False)
 It returns an Iterator object whose contents can be displayed by using for loop

 path  Directory Path. cwd means .


 topdown = True  Travel from top to bottom
KESA PAVAN KUMAR Cell No: 9848461833
134

 onerror = None  On error detected which function has to execute.


 followlinks = True  To visit directories pointed by symbolic links

Eg: To display all contents of Current working directory including sub directories:
1) import os
2) for dirpath,dirnames,filenames in os.walk('.'):
3) print("Current Directory Path:",dirpath)
4) print("Directories:",dirnames)
5) print("Files:",filenames)
6) print()

Output
Current Directory Path: .
Directories: ['com', 'newdir', 'pack1', ' pycache ']
Files: ['abc.txt', 'abcd.txt', 'demo.py', 'durgamath.py', 'emp.csv', 'file1.txt', 'file2.txt',
'file3.
txt', 'files.zip', 'log.txt', 'module1.py', 'mylog.txt', 'newpic.jpg', 'rossum.jpg', 'test.py']

Current Directory Path: .\com


Directories: ['durgasoft', '
pycache '] Files: ['module1.py', '
init .py']
...

Note: To display contents of particular directory, we have to provide that


directory name as argument to walk() function.
os.walk("directoryname")

Q) What is the difference between listdir() and walk() Functions?


In the case of listdir(), we will get contents of specified directory but not
sub directory contents. But in the case of walk() function we will get
contents of specified directory and its sub directories also.

Running Other Programs from Python Program:


OS Module contains system() function to run programs and
commands. It is exactly same as system() function in C
language.

os.system("commad string")
The argument is any command which is executing from DOS.

Eg:
import os
os.system("dir
*.py")
os.system("py
abc.py")
KESA PAVAN KUMAR Cell No: 9848461833
135

How to get Information about a File:


We can get statistics of a file like size, last accessed time,last modified time
etc by using stat() function of os module.
stats = os.stat("abc.txt")

The statistics of a file includes the following parameters:

1) st_mode  Protection Bits


2) st_ino  Inode number
3) st_dev  Device
4) st_nlink  Number of Hard Links
5) st_uid  User id of Owner
6) st_gid  Group id of Owner
7) st_size  Size of File in Bytes
8) st_atime  Time of Most Recent Access
9) st_mtime  Time of Most Recent Modification
10) st_ctime  Time of Most Recent Meta Data Change

Note: st_atime, st_mtime and st_ctime returns the time as number of milli
seconds since Jan 1st 1970, 12:00 AM. By using datetime module from
timestamp() function, we can get exact date and time.

Q) To Print all Statistics of File abc.txt


1) import os
2) stats=os.stat("abc.txt")
3) print(stats)

Output
os.stat_result(st_mode=33206, st_ino=844424930132788,
st_dev=2657980798, st_nlin k=1, st_uid=0, st_gid=0, st_size=22410,
st_atime=1505451446, st_mtime=1505538999
, st_ctime=1505451446)

Q) To Print specified Properties


1) import os
2) from datetime import *
3) stats=os.stat("abc.txt")
4) print("File Size in Bytes:",stats.st_size)
5) print("File Last Accessed Time:",datetime.fromtimestamp(stats.st_atime))
6) print("File Last Modified Time:",datetime.fromtimestamp(stats.st_mtime))

KESA PAVAN KUMAR Cell No: 9848461833


136

Output
File Size in Bytes: 22410
File Last Accessed Time: 2017-09-15 10:27:26.599490
File Last Modified Time: 2017-09-16 10:46:39.245394

Pickling and Unpickling of Objects:


 Sometimes we have to write total state of object to the file and we have to
read total object from the file.
 The process of writing state of object to the file is called pickling and
the process of reading state of an object from the file is called
unpickling.
 We can implement pickling and unpickling by using pickle module of Python.
 pickle module contains dump() function to perform pickling.
pickle.dump(object,f
 pickle module contains load() function to perform unpickling
ile)
obj=pickle.load(fi
le)
pickling
pickle.du
mp
eno: 100
ename: (e1, f)
Durga esal:
10000
e1 eaddr: HYD eno: 100
ename:
Durga esal:
10000
eaddr: HYD

eno: 100 abc.tx


ename: pickle load t
Durga esal: (f)
e2 10000 unpickli
eaddr: HYD ng
Writing and Reading State of Object by using pickle
Module:
1) import pickle
2) class Employee:
3) def init
(self,eno,ename,esal,eaddr):
4) self.eno=en
5) o;
self.ename=ena
6) me;
self.esal=es
7) al;
self.eaddr=ead
8) dr;display(self):
def
9) print(self.eno,"\t",self.ename,"\t",self.esal,"\t",self.e
10) withaddr)
open("emp.dat","wb") as f:
11)
e=Employee(100,"Durga",1000,"H
yd")
KESA PAVAN KUMAR Cell No: 9848461833
137

12) pickle.dump(e,f)
13) print("Pickling of Employee Object completed...")
14)
15) with open("emp.dat","rb") as f:
16) obj=pickle.load(f)
17) print("Printing Employee Information after unpickling")
18) obj.display()

Writing Multiple Employee Objects to the File:


emp.py:
1) class Employee:
2) def init (self,eno,ename,esal,eaddr):
3) self.eno=eno;
4) self.ename=ename;
5) self.esal=esal;
6) self.eaddr=eaddr;
7) def display(self):
8)
9) print(self.eno,"\t",self.ename,"\t",self.esal,"\t",self.eaddr)

pick.py:
1) import emp,pickle
2) f=open("emp.dat","wb")
3) n=int(input("Enter The number of Employees:"))
4) for i in range(n):
5) eno=int(input("Enter Employee Number:"))
6) ename=input("Enter Employee Name:")
7) esal=float(input("Enter Employee Salary:"))
8) eaddr=input("Enter Employee Address:")
9) e=emp.Employee(eno,ename,esal,eaddr)
10) pickle.dump(e,f)
11) print("Employee Objects pickled successfully")

unpick.py:
1) import emp,pickle
2) f=open("emp.dat","rb")
3) print("Employee Details:")
4) while True:
5) try:
6) obj=pickle.load(f)

KESA PAVAN KUMAR Cell No: 9848461833


138

7) obj.display
8) ()
except EOFError:
9) print("All employees
10 Completed")
brea
)11) k
f.close()

KESA PAVAN KUMAR Cell No: 9848461833


139

MULTI
THREADING

KESA PAVAN KUMAR Cell No: 9848461833


140

Multi Tasking:
Executing several tasks simultaneously is the concept of multitasking.

There are 2 types of Multi Tasking


1) Process based Multi Tasking
2) Thread based Multi Tasking

1)Process based Multi Tasking:


Executing several tasks simultaneously where each task is a seperate
independent process is called process based multi-tasking.
E.g.: while typing python program in the editor we can listen mp3 audio
songs from the same system. At the same time we can download a file from
the internet. All these tasks are executing simultaneously and independent
of each other. Hence it is process based multi-tasking.

This type of multi-tasking is best suitable at operating system level.

2)Thread based MultiTasking:


 Executing several tasks simultaneously where each task is a seperate
independent part of the same program, is called Thread based multi-
tasking, and each independent part is called a Thread.
 This type of multi-tasking is best suitable at programmatic level.

Note: Whether it is process based or thread based, the main advantage of


multi-tasking is to improve performance of the system by reducing response
time.

The main important application areas of multi threading are:


1) To implement Multimedia graphics
2) To develop animations
3) To develop video games
4) To develop web and application
servers etc...

Note: Where ever a group of independent jobs are available, then it is highly
recommended to execute simultaneously instead of executing one by one. For
such type of cases we should go for Multi Threading.
 Python provides one inbuilt module "threading" to provide support for
developing threads. Hence developing multi threaded Programs is very
easy in python.
 Every Python Program by default contains one thread which is
nothing but MainThread.

KESA PAVAN KUMAR Cell No: 9848461833


141

Q) Program to print Name of Current executing Thread


1) import threading
2) print("Current Executing Thread:",threading.current_thread().getName())

Output: Current Executing Thread: MainThread

Note: threading module contains function current_thread() which returns the


current executing Thread object. On this object if we call getName() method
then we will get current executing thread name.

The ways of Creating Thread in Python:


We can create a thread in Python by using 3 ways
1) Creating a Thread without using any class
2) Creating a Thread by extending Thread class
3) Creating a Thread without extending Thread class

1)Creating a Thread without using any Class


1) from threading import *
2) def display():
3) for i in range(1,11):
4) print("Child
5) t=Thread(target=display)
Thread") #creating Thread object
6) t.start() #starting of Thread
7) for i in range(1,11):
8) print("Main Thread")

If multiple threads present in our program, then we cannot expect execution


order and hence we cannot expect exact output for the multi threaded
programs. B'z of this we cannot provide exact output for the above program.It
is varied from machine to machine and run to run.

Note: Thread is a pre defined class present in threading module which can
be used to create our own Threads.

2)Creating a Thread by extending Thread Class


We have to create child class for Thread class. In that child class we have
to override run() method with our required job. Whenever we call start()
method then automatically run() method will be executed and performs
our job.

KESA PAVAN KUMAR Cell No: 9848461833


142

1) from threading import


* class MyThread(Thread):
2)

3)
4) defforrun(self):
i in
5) range(10):
print("Child Thread-
1")
6) t=MyThread()
7) t.start()
8) for i in range(10):
9) print("Main Thread-
1")
3)Creating a Thread without extending Thread Class
1) from threading import *
2) class Test:
3) def display(self):
4) for i in range(10):
5) print("Child Thread-2")
6) obj=Test()
7) t=Thread(target=obj.display)
8) t.start()
9) for i in range(10):
10) print("Main Thread-2")

Without Multi Threading


1) from threading import
*2) import time

3)
4) deffor n in numbers:
doubles(numbers):
5) time.sleep(
6) 1)
print("Double:",2*
7) def n)
squares(numbers):
8) for n in numbers:
9) time.sleep(
10 1)
print("Square:",n*
)11) numbers=[1,2,3,4,5,6]
n)
12) begintime=time.time()
13) doubles(numbers)
14) squares(numbers)
15) print("The total time taken:",time.time()-
begintime)

KESA PAVAN KUMAR Cell No: 9848461833


143

With Multi Threading


1) from threading import *
2) import time
3) def doubles(numbers):
4) for n in numbers:
5) time.sleep(1)
6) print("Double:",2*n)
7) def squares(numbers):
8) for n in numbers:
9) time.sleep(1)
10) print("Square:",n*n)
11)
12) numbers=[1,2,3,4,5,6]
13) begintime=time.time()
14) t1=Thread(target=doubles,args=(numbers,))
15) t2=Thread(target=squares,args=(numbers,))
16) t1.start()
17) t2.start()
18) t1.join()
19) t2.join()
20) print("The total time taken:",time.time()-begintime)

Setting and Getting Name of a Thread:


Every thread in python has name. It may be default name generated by
Python or Customized Name provided by programmer.

We can get and set name of thread by using the following Thread class
methods. t.getName()  Returns Name of Thread
t.setName(newName)  To set our own name

Note: Every Thread has implicit variable "name" to represent name of Thread.
1) from threading import *
2) print(current_thread().getName())
3) current_thread().setName("Pawan Kalyan")
4) print(current_thread().getName())
5) print(current_thread().name)

Output
MainThread
Pawan
Kalyan
Pawan
Kalyan

KESA PAVAN KUMAR Cell No: 9848461833


144

Thread Identification Number (ident):


For every thread internally a unique identification number is available. We can
access this id by using implicit variable "ident"

1) from threading import *


2) def test():
3) print("Child Thread")
4) t=Thread(target=test)
5) t.start()
6) print("Main Thread Identification Number:",current_thread().ident)
7) print("Child Thread Identification Number:",t.ident)

Output:
Child Thread
Main Thread Identification Number:
2492 Child Thread Identification
Number: 2768

active_count():
This function returns the number of active threads currently running.

1) from threading import *


2) import time
3) def display():
4) print(current_thread().getName(),"...started")
5) time.sleep(3)
6) print(current_thread().getName(),"...ended")
7) print("The Number of active Threads:",active_count())
8) t1=Thread(target=display,name="ChildThread1")
9) t2=Thread(target=display,name="ChildThread2")
10) t3=Thread(target=display,name="ChildThread3")
11) t1.start()
12) t2.start()
13) t3.start()
14) print("The Number of active Threads:",active_count())
15) time.sleep(5)
16) print("The Number of active Threads:",active_count())

Output:
D:\python_classes>py
test.py The Number of
active Threads: 1
ChildThread1 ...started
ChildThread2 ...started
ChildThread3 ...started
The Number of active Threads: 4

KESA PAVAN KUMAR Cell No: 9848461833


145

ChildThread1
...ended
ChildThread2
...ended
ChildThread3
...ended
The Number of active Threads: 1

enumerate() Function:
This function returns a list of all active threads currently running.

1) from threading import *


2) import time
3) def display():
4) print(current_thread().getName(),"...started")
5) time.sleep(3)
6) print(current_thread().getName(),"...ended")
7) t1=Thread(target=display,name="ChildThread1")
8) t2=Thread(target=display,name="ChildThread2")
9) t3=Thread(target=display,name="ChildThread3")
10) t1.start()
11) t2.start()
12) t3.start()
13) l=enumerate()
14) for t in l:
15) print("Thread Name:",t.name)
16) time.sleep(5)
17) l=enumerate()
18) for t in l:
19) print("Thread Name:",t.name)

Output:
D:\python_classes>py
test.py ChildThread1
...started ChildThread2
...started ChildThread3
...started Thread Name:
MainThread Thread
Name: ChildThread1
Thread Name:
ChildThread2 Thread
Name: ChildThread3
ChildThread1 ...ended
ChildThread2 ...ended
ChildThread3 ...ended
Thread Name:
MainThread

KESA PAVAN KUMAR Cell No: 9848461833


146

isAlive() Method:
isAlive() method checks whether a thread is still executing or not.

1) from threading import *


2) import time
3) def display():
4) print(current_thread().getName(),"...started")
5) time.sleep(3)
6) print(current_thread().getName(),"...ended")
7) t1=Thread(target=display,name="ChildThread1")
8) t2=Thread(target=display,name="ChildThread2")
9) t1.start()
10) t2.start()
11)
12) print(t1.name,"is Alive :",t1.isAlive())
13) print(t2.name,"is Alive :",t2.isAlive())
14) time.sleep(5)
15) print(t1.name,"is Alive :",t1.isAlive())
16) print(t2.name,"is Alive :",t2.isAlive())

Output:
D:\python_classes>py
test.py ChildThread1
...started ChildThread2
...started ChildThread1 is
Alive : True ChildThread2
is Alive : True
ChildThread1 ...ended
ChildThread2 ...ended
ChildThread1 is Alive :
False ChildThread2 is
Alive : False

join() Method:
If a thread wants to wait until completing some other thread then we should
go for join() method.

1) from threading import


*2) import time

3)
4) deffor
display():
i in range(10):
5) print("Seetha
6) Thread")
time.sleep(
7) 2)
8) t=Thread(target=display)
9)
t.start()
KESA PAVAN KUMAR Cell No: 9848461833
147

10) t.join()#This Line executed by Main Thread


11) for i in range(10):
12) print("Rama Thread")

In the above example Main Thread waited until completing child thread.
In this case output is:
Seetha
Thread
Seetha
Thread
Seetha
Thread
Seetha
Thread
Seetha
Thread
Seetha
Thread
Seetha
Thread
Seetha
Thread
Seetha
Thread
Seetha
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread

Note: We can call join() method with time period also.


t.join(seconds)
In this case
KESA thread
PAVAN will wait only specified amount
KUMAR Cell No:of time.
9848461833
148

1) from threading import *


2) import time
3) def display():
4) for i in range(10):
5) print("Seetha Thread")
6) time.sleep(2)
7)
8) t=Thread(target=display)
9) t.start()
10) t.join(5)#This Line executed by Main Thread
11) for i in range(10):
12) print("Rama Thread")

KESA PAVAN KUMAR Cell No: 9848461833


149

In this case Main Thread waited only 5 seconds.

Output
Seetha
Thread
Seetha
Thread
Seetha
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Rama
Thread
Seetha
Thread
Seetha
Thread
Seetha
Thread
Seetha
Thread
Seetha
Thread
Seetha
Thread
Seetha
Thread

Summary of all methods related to threading module and Thread

Daemon Threads:
 The threads which are running in the background are called Daemon Threads.
 The main objective of Daemon Threads is to provide support for
Non Daemon Threads( like main thread)
KESA PAVAN KUMAR Cell No: 9848461833
150

Eg: Garbage Collector


 Whenever Main Thread runs with low memory, immediately PVM runs
Garbage Collector to destroy useless objects and to provide free
memory,so that Main Thread can continue its execution without having
any memory problems.
 We can check whether thread is Daemon or not by using t.isDaemon()
method of Thread class or by using daemon property.

1) from threading import *


2) print(current_thread().isDaemon()) #False
3) print(current_thread().daemon) #False

 We can change Daemon nature by using setDaemon() method of


Thread class. t.setDaemon(True)

KESA PAVAN KUMAR Cell No: 9848461833


151

 But we can use this method before starting of Thread.i.e once thread
started,we cannot change its Daemon nature,otherwise we will get
 RuntimeException:cannot set daemon status of active thread.

1) from threading import *


2) print(current_thread().isDaemon())
3) current_thread().setDaemon(True)

RuntimeError: cannot set daemon status of active thread

Default Nature:
By default Main Thread is always non-daemon.But for the remaining threads
Daemon nature will be inherited from parent to child.i.e if the Parent Thread is
Daemon then child thread is also Daemon and if the Parent Thread is Non
Daemon then ChildThread is also Non Daemon.

1) from threading import *


2) def job():
3) print("Child Thread")
4) t=Thread(target=job)
5) print(t.isDaemon())#False
6) t.setDaemon(True)
7) print(t.isDaemon()) #True

Note: Main Thread is always Non-Daemon and we cannot change its Daemon
Nature b'z it is already started at the beginning only.

Whenever the last Non-Daemon Thread terminates automatically all Daemon


Threads will be terminated.

1) from threading import


* import time
2)

3)
4) deffor
job():
i in range(10):
5) print("Lazy
6) Thread")
time.sleep(
7) 2)
8) t=Thread(target=job)
9)
#t.setDaemon(True)===>Line-
10) t.start()
1
12) print("End Of Main Thread")
11) time.sleep(5)

KESA PAVAN KUMAR Cell No: 9848461833


152

In the above program if we comment Line-1 then both Main Thread and Child
Threads are Non Daemon and hence both will be executed until their
completion.
In this case output is:

Lazy
Thread
Lazy
Thread
Lazy
Thread
End Of Main
Thread Lazy
Thread
Lazy
Thread
Lazy
Thread
Lazy
Thread
Lazy
Thread
Lazy
Thread
Lazy
Thread

If we are not commenting Line-1 then Main Thread is Non-Daemon and


Child Thread is Daemon. Hence whenever MainThread terminates
automatically child thread will be terminated. In this case output is

Lazy
Thread
Lazy
Thread
Lazy
Thread
End of Main Thread

Synchronization:
If multiple threads are executing simultaneously then there may be a chance
of data inconsistency problems.

KESA PAVAN KUMAR Cell No: 9848461833


153

1) from threading import


*2) import time

4) deffor
3) wish(name):
i in range(10):
5) print("Good
6) Evening:",end='')
time.sleep(
7) 2)
print(nam
e)
8) t1=Thread(target=wish,args=("Dhoni",))
9)
t2=Thread(target=wish,args=("Yuvraj"
10) t1.start()
,))

11) t2.start()
Output
Good Evening:Good
Evening:Yuvraj Dhoni

KESA PAVAN KUMAR Cell No: 9848461833


154

Good Evening:Good
Evening:Yuvraj Dhoni
....

 We are getting irregular output b'z both threads are executing


simultaneously wish() function.
 To overcome this problem we should go for synchronization.
 In synchronization the threads will be executed one by one so that we
can overcome data inconsistency problems.
 Synchronization means at a time only one Thread

The main application areas of synchronization are


1) Online Reservation system
2) Funds Transfer from joint
accounts etc

In Python, we can implement synchronization by using the following


1) Lock
2) RLock
3) Semaphore

Synchronization By using Lock Concept:


 Locks are the most fundamental synchronization mechanism provided
by threading module.
 We can create Lock object as follows l = Lock()
 The Lock object can be hold by only one thread at a time.If any other
thread required the same lock then it will wait until thread releases lock.
(Similar to common wash rooms, public telephone booth etc)
 A Thread can acquire the lock by using acquire() Method l.acquire()
 A Thread can release the lock by using release() Method l.release()

Note: To call release() method compulsory thread should be owner of that


lock.i.e thread should has the lock already,otherwise we will get Runtime
Exception saying RuntimeError: release unlocked lock.

1) from threading import *


2) l=Lock()
3) #l.acquire()  1
4) l.release()

If we are commenting line-1 then we will get RuntimeError: release unlocked lock

1) from threading import *


2) import time

KESA PAVAN KUMAR Cell No: 9848461833


155

3) l=Lock()
4) def wish(name):
5)
6) l.acquire
for i in range(10):
()
7) print("Good
8) Evening:",end='')
time.sleep(
9) 2)
print(nam
e)
10) l.release()
11)
12) t1=Thread(target=wish,args=("Dhoni",))
13)
t2=Thread(target=wish,args=("Yuvraj"
14) t3=Thread(target=wish,args=("Kohli",))
,))
16) t2.start()
15)
17) t1.start()
t3.start(
)
In the above program at a time only one thread is allowed to execute wish()
method and hence we will get regular output.

Problem with Simple Lock:


The standard Lock object does not care which thread is currently holding that
lock.If the lock is held and any thread attempts to acquire lock, then it will be
blocked,even the same thread is already holding that lock.

1) from threading import *


2) l=Lock()
3) print("Main Thread trying to acquire Lock")
4) l.acquire()
5) print("Main Thread trying to acquire Lock Again")
6) l.acquire()

Output
D:\python_classes>py test.py
Main Thread trying to acquire
Lock
Main Thread trying to acquire Lock Again
--
In the above Program main thread will be blocked b'z it is trying to acquire the
lock second time.

Note: To kill the blocking thread from windows command prompt we have to
use ctrl+break. Here ctrl+C won't work.

If the Thread calls recursive functions or nested access to resources,then the


thread may trying to acquire the same lock again and again,which may block
our thread.

KESA PAVAN KUMAR Cell No: 9848461833


156

Hence Traditional Locking mechanism won't work for executing recursive functions.

To overcome this problem, we should go for RLock(Reentrant Lock).


Reentrant means the thread can acquire the same lock again and again.If the
lock is held by other threads then only the thread will be blocked.

Reentrant facility is available only for owner thread but not for other threads.

1) from threading import *


2) l=RLock()
3) print("Main Thread trying to acquire Lock")
4) l.acquire()
5) print("Main Thread trying to acquire Lock Again")
6) l.acquire()

In this case Main Thread won't be Locked b'z thread can acquire the lock any
number of times.

This RLock keeps track of recursion level and hence for every acquire() call
compulsory release() call should be available. i.e the number of acquire()
calls and release() calls should be matched then only lock will be released.

Eg:
l=RLock(
)
l.acquire
()
l.acquire
()
l.release
()
l.release
()

After 2 release() calls only the Lock will be released.

Note:
1) Only owner thread can acquire the lock multiple times
2) The number of acquire() calls and release() calls should be matched.

Demo Program for Synchronization by using RLock:


1) from threading import *
2) import time
3) l=RLock()
4) def factorial(n):
5) l.acquire()
6) if n==0:
7) result=1
KESA PAVAN KUMAR Cell No: 9848461833
157

8) else:
9) result=n*factorial(n-1)
10) l.release()
11) return result
12)
13) def results(n):
14) print("The Factorial of",n,"is:",factorial(n))
15)
16) t1=Thread(target=results,args=(5,))
17) t2=Thread(target=results,args=(9,))
18) t1.start()
19) t2.start()

Output:
The Factorial of 5 is: 120
The Factorial of 9 is: 362880

In the above program instead of RLock if we use normal Lock then the thread
will be blocked.

Difference between Lock and RLock


Lock RLock
1) Lock object can be acquired by 1) RLock object can be acquired by
only one thread at a time.Even only one thread at a time, but owner
owner thread also cannot acquire thread can acquire same lock object
multiple times. multiple times.
2) Not suitable to execute 2) Best suitable to execute
recursive functions and nested recursive functions and nested
access calls. access calls.
3) In this case Lock object will takes 3) In this case RLock object will
care only Locked or unlocked and it takes care whether Locked or
never takes care about owner thread unlocked and owner thread
and recursion level. information, recursiion level.

Synchronization by using Semaphore:


☕ In the case of Lock and RLock, at a time only one thread is allowed to execute.
☕ Sometimes our requirement is at a time a particular number of threads are
allowed to access(like at a time 10 memebers are allowed to access
database server,4 members are allowed to access Network connection
etc).To handle this requirement we cannot use Lock and RLock concepts
and we should go for Semaphore concept.
☕ Semaphore can be used to limit the access to the shared resources with
limited capacity.
☕ Semaphore is advanced Synchronization Mechanism.

KESA PAVAN KUMAR Cell No: 9848461833


158

☕ We can create Semaphore object as follows s = Semaphore(counter)


☕ Here counter represents the maximum number of threads are allowed to
access simultaneously. The default value of counter is 1.
☕ Whenever thread executes acquire() method,then the counter value will be
decremented by 1 and if thread executes release() method then the counter
value will be incremented by 1.
☕ i.e for every acquire() call counter value will be decremented and for every
release() call counter value will be incremented.

Case-1: s = Semaphore()
In this case counter value is 1 and at a time only one thread is allowed to
access. It is exactly same as Lock concept.

Case-2: s = Semaphore(3)
In this case Semaphore object can be accessed by 3 threads at a time.The
remaining threads have to wait until releasing the semaphore.

1) from threading import


*2) import time

3) s=Semaphore(2)
4) def wish(name):

5)
6) s.acquire()
for i in range(10):
7) print("Good
8) Evening:",end='')
time.sleep(
9) 2)
print(nam
e)
10) s.release()
11)
12) t1=Thread(target=wish,args=("Dhoni",))
13)
t2=Thread(target=wish,args=("Yuvraj"
14) t3=Thread(target=wish,args=("Kohli",))
,))
16) t5=Thread(target=wish,args=("Pandya",))
15)
t4=Thread(target=wish,args=("Rohit",)
18) t2.start()
)
20) t4.start()
17) t1.start()

19) t3.start()
In the above program at a time 2 threads are allowed to access semaphore
and hence 2 threads are allowed to execute wish() function.
21) t5.start()

KESA PAVAN KUMAR Cell No: 9848461833


159

Bounded Semaphore:
Normal Semaphore is an unlimited semaphore which allows us to call
release() method any number of times to increment counter.The number of
release() calls can exceed the number of acquire() calls also.

1) from threading import *


2) s=Semaphore(2)
3) s.acquire()
4) s.acquire()
5) s.release()
6) s.release()
7) s.release()
8) s.release()
9) print("End")

☕ It is valid because in normal semaphore we can call release() any number of times.
☕ BounedSemaphore is exactly same as Semaphore except that the number
of release() calls should not exceed the number of acquire()
calls,otherwise we will get ValueError: Semaphore released too many
times

1) from threading import *


2) s=BoundedSemaphore(2)
3) s.acquire()
4) s.acquire()
5) s.release()
6) s.release()
7) s.release()
8) s.release()
9) print("End")

ValueError: Semaphore released too many times


It is invalid b'z the number of release() calls should not exceed the number
of acquire() calls in BoundedSemaphore.

Note: To prevent simple programming mistakes, it is recommended to use


BoundedSemaphore over normal Semaphore.

Difference between Lock and Semaphore:


At a time Lock object can be acquired by only one thread, but Semaphore
object can be acquired by fixed number of threads specified by counter
value.

KESA PAVAN KUMAR Cell No: 9848461833


160

Conclusion:
The main advantage of synchronization is we can overcome data
inconsistency problems.But the main disadvantage of synchronization is it
increases waiting time of threads and creates performance problems. Hence if
there is no specific requirement then it is not recommended to use
synchronization.

Inter Thread Communication:


☕ Some times as the part of programming requirement, threads are required to
communicate with each other. This concept is nothing but interthread
communication.
☕ Eg: After producing items Producer thread has to communicate with
Consumer thread to notify about new item.Then consumer thread can
consume that new item.
☕ In Python, we can implement interthread communication by using the following ways
1) Event
2) Condition
3) Queu
e etc

Inter Thread Communication by using Event


Objects:
☕ Event object is the simplest communication mechanism between the
threads. One thread signals an event and other thereds wait for it.
☕ We can create Event object as follows...
☕ event = threading.Event()
☕ Event manages an internal flag that can set() or clear()
☕ Threads can wait until event set.

Methods of Event Class:


1) set()  internal flag value will become True and it represents GREEN
signal for all waiting threads.
2) clear()  inernal flag value will become False and it represents RED
signal for all waiting threads.
3) isSet()  This method can be used whether the event is set or not
4) wait()|wait(seconds)  Thread can wait until event is set

Pseudo Code:
event = threading.Event()
#consumer thread has to wait until event
is set event.wait()
#producer thread can set or clear
event event.set()
event.clear()

KESA PAVAN KUMAR Cell No: 9848461833


161

Demo Program-1:

1) from threading import *


2) import time
3) def producer():
4) time.sleep(5)
5) print("Producer thread producing items:")
6) print("Producer thread giving notification by setting event")
7) event.set()
8) def consumer():
9) print("Consumer thread is waiting for updation")
10) event.wait()
11) print("Consumer thread got notification and consuming items")
12
13) event=Event()
)
15) t1=Thread(target=producer)
14) t2=Thread(target=consumer)

17) t1.start()
16) t2.start()

Output:
Consumer thread is waiting for
updation Producer thread
producing items
Producer thread giving notification by setting
event Consumer thread got notification and
consuming items

Demo Program-2:

1) from threading
import * time
2) import

3)
4) defwhile
trafficpolice():
True:
5) time.sleep(1
6) 0)
print("Traffic Police Giving GREEN
7) Signal")
event.set
8) ()
time.sleep(2
9) 0)
print("Traffic Police Giving RED
10 Signal")
event.clear
)11) def ()
driver():
12) num=0

13)
14 while
print("Drivers waiting for GREEN
True:
)
15 Signal")
event.wait
)16 ()
print("Traffic Signal is GREEN...Vehicles can
)17 move")
while
) event.isSet():
KESA PAVAN KUMAR Cell No: 9848461833
162

18) num=num+1
19) print("Vehicle No:",num,"Crossing the Signal")
20) time.sleep(2)
21) print("Traffic Signal is RED...Drivers have to wait")
22) event=Event()
23) t1=Thread(target=trafficpolice)
24) t2=Thread(target=driver)
25) t1.start()
26) t2.start()

In the above program driver thread has to wait until Trafficpolice thread sets
event.ie until giving GREEN signal.Once Traffic police thread sets event(giving
GREEN signal),vehicles can cross the signal. Once traffic police thread clears
event (giving RED Signal)then the driver thread has to wait.

Inter Thread Communication by using Condition Object:


☕ Condition is the more advanced version of Event object for interthread
communication.A condition represents some kind of state change in the
application like producing item or consuming item. Threads can wait for
that condition and threads can be notified once condition happend.i.e
Condition object allows one or more threads to wait until notified by
another thread.
☕ Condition is always associated with a lock (ReentrantLock).
☕ A condition has acquire() and release() methods that call the
corresponding methods of the associated lock.
☕ We can create Condition object as follows condition = threading.Condition()

Methods of Condition:
1) acquire()  To acquire Condition object before producing or
consuming items.i.e thread acquiring internal lock.

2) release()  To release Condition object after producing or consuming


items. i.e thread releases internal lock

3) wait()|wait(time)  To wait until getting Notification or time expired

4) notify()  To give notification for one waiting thread

5) notifyAll()  To give notification for all waiting threads

KESA PAVAN KUMAR Cell No: 9848461833


163

Case Study:
The producing thread needs to acquire the Condition before producing item
to the resource and notifying the consumers.

#Producer Thread
...generate item..
condition.acquir
e()
...add item to the resource...
condition.notify()#signal that a new item is
available(notifyAll()) condition.release()

The Consumer must acquire the Condition and then it can consume items
from the resource

#Consumer
Thread
condition.acquir
condition.wait()
e()
consume item
condition.releas
e()

Demo Program-1:
1) from threading import *
2) def consume(c):
3) c.acquire()
4) print("Consumer waiting for updation")
5) c.wait()
6) print("Consumer got notification & consuming the item")
7) c.release()
8)
9) def produce(c):
10) c.acquire()
11) print("Producer Producing Items")
12) print("Producer giving Notification")
13) c.notify()
14) c.release()
15)
16) c=Condition()
17) t1=Thread(target=consume,args=(c,))
18) t2=Thread(target=produce,args=(c,))
19) t1.start()
20) t2.start()

KESA PAVAN KUMAR Cell No: 9848461833


164

Output
Consumer waiting for
updation Producer
Producing Items Producer
giving Notification
Consumer got notification & consuming the item

Demo Program-2:

1) from threading import


*2) import time

3) import random
4) items=[]

5)
6) def produce(c):
while True:
7) c.acquire
8) ()
item=random.randint(1,1
9) 00)
print("Producer Producing
10 Item:",item)
items.append(ite
)11 m)
print("Producer giving
)
12 Notification")
c.notify
)13 ()
c.release
)14 ()
time.sleep(
)15) 5)
16) def consume(c):
17) while
True: c.acquire
18
)19 ()
print("Consumer waiting for
)20 updation")
c.wait(
)21 )print("Consumer consumed the
)22 item",items.pop())
c.release
)23 ()
time.sleep(
)
24 5)
)25) c=Condition()
26) t1=Thread(target=consume,args=(c,))
27)
t2=Thread(target=produce,args=(c,
28) t1.start()
))

29) t2.start()
Output
Consumer waiting for
updation Producer
Producing Item: 49 Producer
giving Notification
Consumer consumed the
item 49
.....

KESA PAVAN KUMAR Cell No: 9848461833


165

In the above program Consumer thread expecting updation and hence it is


responsible to call wait() method on Condition object.
Producer thread performing updation and hence it is responsible to call
notify() or notifyAll() on Condition object.

Inter Tread Communication by using Queue:


☕ Queues Concept is the most enhanced Mechanism for interthread
communication and to share data between threads.
☕ Queue internally has Condition and that Condition has Lock.Hence
whenever we are using Queue we are not required to worry about
Synchronization.
☕ If we want to use Queues first we should import queue module import queue
☕ We can create Queue object as follows q = queue.Queue()

Important Methods of Queue:


1) put(): Put an item into the queue.
2) get(): Remove and return an item from the queue.

Producer Thread uses put() method to insert data in the queue. Internally this
method has logic to acquire the lock before inserting data into queue. After
inserting data lock will be released automatically.

put() method also checks whether the queue is full or not and if queue is full
then the Producer thread will entered in to waiting state by calling wait()
method internally.

Consumer Thread uses get() method to remove and get data from the queue.
Internall
y this method has logic to acquire the lock before removing data from the
queue.Once removal completed then the lock will be released automatically.

If the queue is empty then consumer thread will entered into waiting state by
calling wait() method internally.Once queue updated with data then the thread
will be notified automatically.

Note: The Queue Module takes care of locking for us which is a great Advantage.

1) from threading import *


2) import time
3) import random
4) import queue
5) def produce(q):
6) while True:
7) item=random.randint(1,100)
8) print("Producer Producing
9) Item:",item)
q.put(item
)

KESA PAVAN KUMAR Cell No: 9848461833


166

10) print("Producer giving Notification")


11) time.sleep(5)
12) def consume(q):
13) while True:
14) print("Consumer waiting for updation")
15) print("Consumer consumed the item:",q.get())
16) time.sleep(5)
17)
18) q=queue.Queue()
19) t1=Thread(target=consume,args=(q,))
20) t2=Thread(target=produce,args=(q,))
21) t1.start()
22) t2.start()

Output
Consumer waiting for
updation Producer
Producing Item: 58 Producer
giving Notification Consumer
consumed the item: 58

Types of Queues:
Python Supports 3 Types of Queues.

1) FIFO Queue:
q = queue.Queue()
This is Default Behaviour. In which order we put items in the queue, in the
same order the items will come out (FIFO-First In First Out).

1) import queue
2) q=queue.Queue()
3) q.put(10)
4) q.put(5)
5) q.put(20)
6) q.put(15)
7) while not
q.empty():
8) print(q.get(),end ')
='

Output: 10 5 20 15

KESA PAVAN KUMAR Cell No: 9848461833


167

2) LIFO Queue:
The removal will be happend in the reverse order of Insertion (Last In First Out)

1) import queue
2) q=queue.LifoQueue()
3) q.put(10)
4) q.put(5)
5) q.put(20)
6) q.put(15)
7) while not
q.empty():
8) print(q.get(),end ')
='

Output: 15 20 5 10

3) Priority Queue:
The elements will be inserted based on some priority order.

1) import queue
2) q=queue.PriorityQueue()
3) q.put(10)
4) q.put(5)
5) q.put(20)
6) q.put(15)
7) while not
q.empty():
8) print(q.get(),end ')
='

Output: 5 10 15 20

Eg 2: If the data is non-numeric, then we have to provide our data in the form
of tuple. (x,y)
x is priority
y is our element

1) import queue
2) q=queue.PriorityQueue()
3) q.put((1,"AAA"))
4) q.put((3,"CCC"))
5) q.put((2,"BBB"))
6) q.put((4,"DDD"))
7) while not q.empty():
8) print(q.get()[1],end ')
='

Output: AAA BBB CCC DDD


KESA PAVAN KUMAR Cell No: 9848461833
168

Good Programming Practices with usage of Locks:


Case-1:
It is highly recommended to write code of releasing locks inside finally
block.The advantage is lock will be released always whether exception
raised or not raised and whether handled or not handled.

l=
threading.Lock()
l.acquire()
try:
perform required safe
operations finally:
l.release()

Demo Program:
1) from threading import
*2) import time

3) l=Lock()
4) def wish(name):

5)
6) l.acquire()
try:
7) for i in
8) range(10):
print("Good
9) Evening:",end='')
time.sleep(
10 2)
print(nam
)11) finally: e)
12 l.release
)13) ()
14) t1=Thread(target=wish,args=("Dhoni",))
15)
t2=Thread(target=wish,args=("Yuvraj"
16) t3=Thread(target=wish,args=("Kohli",))
,))
18) t2.start()
17)
19) t1.start()
t3.start(
)
Case-2:
 It is highly recommended to acquire lock by using with statement. The main
advantage of with statement is the lock will be released automatically once
control reaches end of with block and we are not required to release
explicitly.
 This is exactly same as usage of with statement for files.

KESA PAVAN KUMAR Cell No: 9848461833


169

Example for File:


with open('demo.txt','w') as f:
f.write("Hello...")

Example for Lock:


lock =
threading.Lock()
with lock:
perform required safe
operations lock will be
released automatically

Demo Program:
1) from threading import
*2) import time

3) lock=Lock()
4) def wish(name):

5)
6) with
for lock:
i in
7) range(10):
print("Good
8) Evening:",end='')
time.sleep(
9) 2)
print(nam
e)
10) t1=Thread(target=wish,args=("Dhoni",))
11)
t2=Thread(target=wish,args=("Yuvraj"
12) t3=Thread(target=wish,args=("Kohli",))
,))
14) t2.start()
13) t1.start()

15) t3.start()
Q) What is the Advantage of using with Statement to acquire a Lock in
Threading?
Lock will be released automatically once control reaches end of with block
and we are not required to release explicitly.

Note: We can use with statement in multithreading for the following cases:

1) Lock
2) RLock
3) Semaphore
4) Condition

KESA PAVAN KUMAR Cell No: 9848461833


170

PYTHON
DATABASE
PROGRAMMING

KESA PAVAN KUMAR Cell No: 9848461833


171

Storage Areas
As the Part of our Applications, we required to store our Data like Customers
Information, Billing Information, Calls Information etc.

To store this Data, we required Storage Areas. There are 2 types of Storage Areas.

1) Temporary Storage Areas


2) Permanent Storage Areas

1) Temporary Storage Areas:


 These are the Memory Areas where Data will be stored
temporarily. Eg: Python objects like List, Tuple, Dictionary.
 Once Python program completes its execution then these objects will
be destroyed automatically and data will be lost.

2) Permanent Storage Areas:


 Also known as Persistent Storage Areas. Here we can store Data
permanently. Eg: File Systems, Databases, Data warehouses, Big
Data Technologies etc

File Systems:
File Systems can be provided by Local operating System. File Systems are
best suitable to store very less Amount of Information.

Limitations:
1) We cannot store huge Amount of Information.
2) There is no Query Language support and hence operations will become very
complex.
3) There is no Security for Data.
4) There is no Mechanism to prevent duplicate Data. Hence there may be a
chance of Data Inconsistency Problems.

To overcome the above Problems of File Systems, we should go for Databases.

Databases:
1) We can store Huge Amount of Information in the Databases.
2) Query Language Support is available for every Database and hence we
can perform Database Operations very easily.
3) To access Data present in the Database, compulsory username and
pwd must be required. Hence Data is secured.
4) Inside Database Data will be stored in the form of Tables. While developing
Database Table Schemas, Database Admin follow various Normalization
Techniques and can implement various Constraints like Unique Key
Constrains, Primary Key Constraints etc which prevent Data Duplication.
Hence there is no chance of Data Inconsistency Problems.

KESA PAVAN KUMAR Cell No: 9848461833


172

Limitations of Databases:
1) Database cannot hold very Huge Amount of Information like Terabytes of Data.
2) Database can provide support only for Structured Data (Tabular Data OR
Relational Data) and cannot provide support for Semi Structured Data (like
XML Files) and Unstructured Data (like Video Files, Audio Files, Images
etc)

To overcome these Problems we should go for more Advanced Storage Areas


like Big Data Technologies, Data warehouses etc.

Python Database Programming:


 Sometimes as the part of Programming requirement we have to
connect to the database and we have to perform several operations like
creating tables, inserting data, updating data, deleting data, selecting
data etc.
 We can use SQL Language to talk to the database and we can use Python
to send those SQL commands to the database.
 Python provides inbuilt support for several databases like Oracle,
MySql, SqlServer, GadFly, sqlite, etc.
 Python has seperate module for each database.
Eg: cx_Oralce module for communicating with Oracle
database pymssql module for communicating with
Microsoft Sql Server

Standard Steps for Python database Programming:


1) Import database specific module
Eg: import cx_Oracle
2) Establish Connection between Python Program and database.
We can create this Connection object by using connect() function of
the module. con = cx_Oracle.connect(datbase information)
Eg: con = cx_Oracle.connect('scott/tiger@localhost')
3) To execute our sql queries and to hold results some special object is
required, which is nothing but Cursor object. We can create Cursor object
by using cursor() method.
cursor = con.cursor()

4) Execute SQL Queries By using Cursor object. For this we can use the following
methods
⚽ execute(sqlquery)  To execute a Single SQL Query
⚽ executescript(sqlqueries)  To execute a String of SQL Queries
seperated by semi- colon ';'
⚽ executemany()  To execute a Parameterized Query.
Eg: cursor.execute("select * from employees")

KESA PAVAN KUMAR Cell No: 9848461833


173

5) Commit OR Rollback changes based on our requirement in the case of


DML Queries (insert|update|delete)

commit()  Saves the changes to the database


rollback()  rolls all temporary changes back

6) Fetch the result from the Cursor object in the case of


select queries fetchone()  To fetch only one row
fetchall()  To fetch all rows and it returns a list of
rows fecthmany(n)  To fetch first n rows

Eg 1: data =
cursor.fetchone()
print(data)

Eg 2: data =
cursor.fetchall() for
row in data:
print(row)

7) Close the Resources


After completing our operations it is highly recommended to close the
resources in the reverse order of their opening by using close() methods.
cursor.clos
e()
con.close()

Note: The following is the list of all important methods which can be used for
python database programming.

⚽ connect()
⚽ cursor()
⚽ execute()
⚽ executescript()
⚽ executemany()
⚽ commit()
⚽ rollback()
⚽ fetchone()
⚽ fetchall()
⚽ fetchmany(n)
⚽ fetch
⚽ close()

These methods won't be changed from database to database and same for all
databases.

KESA PAVAN KUMAR Cell No: 9848461833


174

Working with Oracle Database:


From Python Program if we want to communicate with any database, some
translator must be required to translate Python calls into Database specific
calls and Database specific calls into Python calls.This translator is
nothing but Driver/Connector.

Diagram

For Oracle database the name of driver needed is cx_Oracle.


cx_Oracle is a Python extension module that enables access to Oracle
Database.It can be used for both Python2 and Python3. It can work with any
version of Oracle database like 9,10,11 and 12.

Installing cx_Oracle:
From Normal Command Prompt (But not from Python console) execute
the following command

D:\python_classes>pip install

cx_Oracle Collecting cx_Oracle


Downloading cx_Oracle-6.0.2-cp36-cp36m-win32.whl
(100kB) 100% | | 102kB 256kB/s
Installing collected packages: cx-
Oracle Successfully installed cx-
Oracle-6.0.2

How to Test Installation:


From python console execute the following command:
>>> help("modules")

In the output we can see cx_Oracle


....
_multiprocessin crypt ntpath timeit
g
_opcode csv nturl2path tkinter
_operator csvr numbers token
_osx_support csvw opcode tokenize
_overlapped ctypes operator trace
_pickle curses optparse traceback
_pydecimal custexcept os tracemallo
c
_pyio cx_Oracle parser try
_random data pathlib tty
_sha1 datetime pdb turtle
_sha256 dbm pick turtledem
o
_sha3 decimal pickle types
_sha512 demo pickletools typing
KESA PAVAN KUMAR Cell No: 9848461833
175

_signal difflib pip unicodedata


_sitebuiltins dis pipes unittest
_socket distutils pkg_resourc unpick
es
_sqlite3 doctest pkgutil update
_sre dummy_threadin platform urllib
g
_ssl durgamath plistlib uu
_stat easy_install polymorph uuid
.....

App 1) Program to Connect with Oracle Database


and print its Version
1) import cx_Oracle
2) con=cx_Oracle.connect('scott/tiger@localhost')
3) print(con.version)
4) con.close()

Output
D:\python_classes>py
db1.py 11.2.0.2.0

App 2) Write a Program to Create Employees


Table in the Oracle Database
employees(eno,ename,esal,eaddr)

1) import cx_Oracle
2) try:
3) con=cx_Oracle.connect('scott/tiger@localhost')
4) cursor=con.cursor()
5) cursor.execute("create table employees(eno number,ename
varchar2(10),esal n umber(10,2),eaddr varchar2(10))")
6) print("Table created successfully")
7) except cx_Oracle.DatabaseError as e:
8) if con:
9) con.rollbac
10 k()
print("There is a problem with
)11) sql",e)
finally:
12) if cursor:
13 cursor.clos
)14) if con:
e()
15 con.clos
) e()

KESA PAVAN KUMAR Cell No: 9848461833


176

App 3) Write a Program to Drop Employees


Table from Oracle Database?
1) import cx_Oracle
2) try:
3)
4) con=cx_Oracle.connect('scott/tiger@loca
cursor=con.cursor()
lhost')
6) print("Table dropped successfully")
5) cursor.execute("drop table employees")
8) if con:
7) except cx_Oracle.DatabaseError as e:
9) con.rollbac
10 k()
print("There is a problem with
)11) sql",e)
finally:
12) if cursor:
13 cursor.clos
)14) if con:
e()
15 con.clos
) e()
App 3) Write a Program to Insert a Single Row in the
Employees Table
1) import cx_Oracle
2) try:
3) con=cx_Oracle.connect('scott/tiger@localhost')
4) cursor=con.cursor()
5) cursor.execute("insert into employees values(100,'Durga',1000,'Hyd')")
6) con.commit()
7) print("Record Inserted Successfully")
8) except cx_Oracle.DatabaseError as e:
9) if con:
10) con.rollback()
11) print("There is a problem with sql",e)
12) finally:
13) if cursor:
14) cursor.close()
15) if con:
16) con.close()

Note: While performing DML Operations (insert|update|delte), compulsory we


have to use commit() method,then only the results will be reflected in the
database.

KESA PAVAN KUMAR Cell No: 9848461833


177

App 4) Write a Program to Insert Multiple Rows in


the Employees Table by using
executemany() Method
1) import cx_Oracle
2) try:
3) con=cx_Oracle.connect('scott/tiger@localhost')
4) cursor=con.cursor()
5) sql="insert into employees values(:eno,:ename,:esal,:eaddr)"
6) records=[(200,'Sunny',2000,'Mumbai'),
7) (300,'Chinny',3000,'Hyd'),
8) (400,'Bunny',4000,'Hyd')]
9) cursor.executemany(sql,records)
10) con.commit()
11) print("Records Inserted Successfully")
12) except cx_Oracle.DatabaseError as e:
13) if con:
14) con.rollback()
15) print("There is a problem with sql",e)
16) finally:
17) if cursor:
18) cursor.close()
19) if con:
20) con.close()

App 5) Write a Program to Insert Multiple Rows in the


Employees Table with Dynamic Input from the
Keyboard?
1) import cx_Oracle
2) try:
3) con=cx_Oracle.connect('scott/tiger@localhost')
4) cursor=con.cursor()
5) while True:
6) eno=int(input("Enter Employee Number:"))
7) ename=input("Enter Employee Name:")
8) esal=float(input("Enter Employee Salary:"))
9) eaddr=input("Enter Employee Address:")
10) sql="insert into employees values(%d,'%s',%f,'%s')"
11) cursor.execute(sql %(eno,ename,esal,eaddr))
12) print("Record Inserted Successfully")
13) option=input("Do you want to insert one more record[Yes|No] :")
14) if option=="No":
15) con.commit()
16) break

KESA PAVAN KUMAR Cell No: 9848461833


178

17) except
cx_Oracle.DatabaseError
18) if con: as e:
19 con.rollbac
)20 k()
print("There is a problem with sql
)21) :",e)
finally:
22) if cursor:
23 cursor.clos
)
24) e()
if con:
25 con.clos
) e()
App 6) Write a Program to Update Employee Salaries with
Increment for the certain Range with Dynamic Input
Eg: Increment all employee salaries by 500 whose salary < 5000

1) import cx_Oracle
2) try:
3) con=cx_Oracle.connect('scott/tiger@localhost')
4) cursor=con.cursor()
5) increment=float(input("Enter Increment Salary:"))
6) salrange=float(input("Enter Salary Range:"))
7) sql="update employees set esal=esal+%f where
esal<%f"
8) cursor.execute(sql %(increment,salrange))
9) print("Records Updated Successfully")
10) con.commit()
11) except cx_Oracle.DatabaseError as e:
12) if con:
13 con.rollbac
)
14 k()
print("There is a problem with sql
)15) :",e)
finally:
16) if cursor:
17 cursor.clos
)18) if con:
e()
19 con.clos
) e()
App 7) Write a Program to Delete Employees
whose Salary Greater provided Salary as
Dynamic Input?
Eg: delete all employees whose salary > 5000

1) import cx_Oracle
2) try:
3) con=cx_Oracle.connect('scott/tiger@localhost')
4) cursor=con.cursor()
5) cutoffsalary=float(input("Enter CutOff Salary:"))

KESA PAVAN KUMAR Cell No: 9848461833


179

6) sql="delete from employees where esal>%f"


7) cursor.execute(sql %(cutoffsalary))
8) print("Records Deleted Successfully")
9) con.commit()
10) except cx_Oracle.DatabaseError as e:
11) if con:
12) con.rollback()
13) print("There is a problem with sql :",e)
14) finally:
15) if cursor:
16) cursor.close()
17) if con:
18) con.close()

App 8) Write a Program to Select all Employees


info by using fetchone() Method?
1) import cx_Oracle
2) try:
3) con=cx_Oracle.connect('scott/tiger@localhost')
4) cursor=con.cursor()
5) cursor.execute("select * from employees")
6) row=cursor.fetchone()
7) while row is not None:
8) print(row)
9) row=cursor.fetchone()
10) except cx_Oracle.DatabaseError as e:
11) if con:
12 con.rollback()
)
13 print("There is a problem with sql :",e)
)
14) finally:
15) if cursor:
16 cursor.close()
)
17) if con:
18 con.close()
)

App 9) Write a Program to select all Employees info


by using fetchall() Method?
1) import cx_Oracle
2) try:
3) con=cx_Oracle.connect('scott/tiger@localhost')
4) cursor=con.cursor()
KESA PAVAN KUMAR Cell No: 9848461833
180

5) cursor.execute("select * from employees")


6) data=cursor.fetchall()
7) for row in data:
8) print("Employee Number:",row[0])
9) print("Employee Name:",row[1])
10) print("Employee Salary:",row[2])
11) print("Employee Address:",row[3])
12) print()
13) print()
14) except cx_Oracle.DatabaseError as e:
15) if con:
16) con.rollback()
17) print("There is a problem with sql :",e)
18) finally:
19) if cursor:
20) cursor.close()
21) if con:
22) con.close()

App 10) Write a Program to select Employees info by using


fetchmany() Method and the required Number of Rows
will be provided as Dynamic Input?
1) import cx_Oracle
2) try:
3) con=cx_Oracle.connect('scott/tiger@localhost')
4) cursor=con.cursor()
5) cursor.execute("select * from employees")
6) n=int(input("Enter the number of required rows:"))
7) data=cursor.fetchmany(n)
8) for row in data:
9) print(row)
10) except cx_Oracle.DatabaseError as e:
11) if con:
12) con.rollback()
13) print("There is a problem with sql :",e)
14) finally:
15) if cursor:
16) cursor.close()
17) if con:
18) con.close()

KESA PAVAN KUMAR Cell No: 9848461833


181

Output
D:\python_classes>py test.py
Enter the number of required
rows:3 (100, 'Durga', 1500.0,
'Hyd')
(200, 'Sunny', 2500.0, 'Mumbai')
(300, 'Chinny', 3500.0, 'Hyd')

D:\python_classes>py test.py
Enter the number of required
rows:4 (100, 'Durga', 1500.0,
'Hyd')
(200, 'Sunny', 2500.0, 'Mumbai')
(300, 'Chinny', 3500.0, 'Hyd')
(400, 'Bunny', 4500.0, 'Hyd')

Working with MySQL Database:


Current version: 5.7.19
Vendor: SUN Micro Systems/Oracle
Corporation Open Source and Freeware
Default Port:
3306 Default
user: root

Note: In MySQL, everything we have to work with our own databases, which
are also known as Logical Databases.

The following are 4 Default Databases available in MySQL.


 information_schema
 mysql
 performance_schema
 test

In the above diagram only one physical database is available and 4 logical
databases are available.

Commonly used Commands in MySQL:


1) To Know Available Databases
mysql> show databases;

2) To Create Our Own Logical Database


mysql> create database durgadb;

3) To Drop Our Own Database


mysql> drop database durgadb;

KESA PAVAN KUMAR Cell No: 9848461833


182

4) To Use a Particular Logical Database


mysql> use durgadb; OR mysql> connect durgadb;

5) To Create a Table
create table employees(eno int(5) primary key,ename varchar(10),esal
double(10,2), eaddr varchar(10));

6) To Insert Data
insert into employees
values(100,'Durga',1000,'Hyd'); insert into
employees values(200,'Ravi',2000,'Mumbai');

In MySQL instead of single quotes we can use double quotes also.

Driver/Connector Information:
From Python program if we want to communicates with MySql database,
compulsory some translator is required to convert python specific calls into
mysql database specific calls and mysql database specific calls into python
specific calls. This translator is nothing but Driver or Connector.

We have to download connector seperately from mysql


database.
https://dev.mysql.com/downloads/connector/python/2.1.h
tml

How to Check Installation:


From python console we have to use help("modules")
In the list of modules, compulsory MySQL should be there.

Note: In the case of Python3.4 we have to set PATH and PYTHONPATH

explicitly PATH=C:\Python34
PYTHONPATH=C:\Python34\Lib\site-packages

Q) Write a Program to Create Table, Insert Data and


display Data by using MySQL Database
1) import mysql.connector
2) try:
3)
con=mysql.connector.connect(host='localhost',database='durgadb',user='root',
p
assword='root')
4) cursor=con.cursor()
5) cursor.execute("create table employees(eno int(5) primary key,ename
varchar(1
0),esal
KESA double(10,2),eaddr
PAVAN KUMAR varchar(10))")Cell No: 9848461833
183

6) print("Table Created...")
7)
8) sql = "insert into employees(eno, ename, esal, eaddr) VALUES(%s, %s,
%s, %s)"
9) records=[(100,'Sachin',1000,'Mumbai'),
10) (200,'Dhoni',2000,'Ranchi'),
11) (300,'Kohli',3000,'Delhi')]
12) cursor.executemany(sql,records)
13) con.commit()
14) print("Records Inserted Successfully...")
15) cursor.execute("select * from employees")
16) data=cursor.fetchall()
17) for row in data:
18) print("Employee Number:",row[0])
19) print("Employee Name:",row[1])
20) print("Employee Salary:",row[2])
21) print("Employee Address:",row[3])
22) print()
23) print()
24) except mysql.connector.DatabaseError as e:
25) if con:
26) con.rollback()
27) print("There is a problem with sql :",e)
28) finally:
29) if cursor:
30) cursor.close()
31) if con:
32) con.close()

Q) Write a Program to Copy Data present in


Employees Table of MySQL Database into
Oracle Database
1) import mysql.connector
2) import cx_Oracle
3) try:
4)
con=mysql.connector.connect(host='localhost',database='durgadb',us
er='root',p
assword='root')
5) cursor=con.cursor()
6) cursor.execute("select * from employees")
7) data=cursor.fetchall()
8) list=[]
9) for row in data:
10) t=(row[0],row[1],row[2],row[3])
11) list.append(t)
KESA PAVAN KUMAR Cell No: 9848461833
184

12) except mysql.connector.DatabaseError as e:

KESA PAVAN KUMAR Cell No: 9848461833


185

13) if con:
14) con.rollback()
15) print("There is a problem with MySql :",e)
16) finally:
17) if cursor:
18) cursor.close()
19) if con:
20) con.clos
e() 21)
22) try:
23) con=cx_Oracle.connect('scott/tiger@localhost')
24) cursor=con.cursor()
25) sql="insert into employees values(:eno,:ename,:esal,:eaddr)"
26) cursor.executemany(sql,list)
27) con.commit()
28) print("Records Copied from MySQL Database to Oracle Database
Successfully")

29) except cx_Oracle.DatabaseError as e:


30) if con:
31) con.rollback()
32) print("There is a problem with sql",e)
33) finally:
34) if cursor:
35) cursor.close()
36) if con:
37) con.close()

https://dev.mysql.com/downloads/connector/python/2.1.html

1) create table employees(eno int(5) primary key,ename varchar(10),esal


double(10,2
),eaddr varchar(10));
2) insert into employees values(100,'Durga',1000,'Hyd');
3) insert into employees values(200,'Ravi',2000,'Mumbai');
4) insert into employees values(300,'Shiva',3000,'Hyd');

KESA PAVAN KUMAR Cell No: 9848461833


186

REGULAR
EXPRESSIONS
&
WEB SCRAPING

KESA PAVAN KUMAR Cell No: 9848461833


187

☕ If we want to represent a group of Strings according to a particular


format/pattern then we should go for Regular Expressions.
☕ i.e Regualr Expressions is a declarative mechanism to represent a group of
Strings accroding to particular format/pattern.
☕ Eg 1: We can write a regular expression to represent all mobile numbers
☕ Eg 2: We can write a regular expression to represent all mail ids.

☕ The main important application areas of Regular Expressions are


1) To develop validation frameworks/validation logic
2) To develop Pattern matching applications (ctrl-f in windows, grep in UNIX etc)
3) To develop Translators like compilers, interpreters etc
4) To develop digital circuits
5) To develop communication protocols like TCP/IP, UDP etc.

☕ We can develop Regular Expression Based applications by using python module: re


☕ This module contains several inbuilt functions to use Regular Expressions
very easily in our applications.

1) compile()
Returns Module contains compile() Function to compile a Pattern into
RegexObject. pattern = re.compile("ab")

2) finditer():
Returns an Iterator object which yields Match object for every
Match matcher = pattern.finditer("abaababa")

On Match object we can call the following methods.


1) start()  Returns start index of the match
2) end()  Returns end+1 index of the match
3) group()  Returns the matched string

1) import re count=0
2) pattern=re.compile("ab")
3) matcher=pattern.finditer("abaababa")
4) for match in matcher:
5) count+=1
6) print(match.start(),"...",match.end(),"...",match.group())
7) print("The number of occurrences: ",count)

Output:
0 ... 2 ... ab
3 ... 5 ... ab
5 ... 7 ... ab

KESA PAVAN KUMAR Cell No: 9848461833


188

The number of occurrences: 3

Note: We can pass pattern directly as argument to finditer() function.


1) import re
2) count=0
3) matcher=re.finditer("ab","abaababa")
4) for match in matcher:
5) count+=1
6) print(match.start(),"...",match.end(),"...",match.group())
7) print("The number of occurrences: ",count)

Output:
0 ... 2 ... ab
3 ... 5 ... ab
5 ... 7 ... ab
The number of occurrences: 3

Character Classes:
We can use character classes to search a group of characters

1) [abc]  Either a OR b OR c
2) [^abc]  Except a and b and c
3) [a-z]  Any Lower case alphabet symbol
4) [A-Z]  Any upper case alphabet symbol
5) [a-zA-Z]  Any alphabet symbol
6) [0-9]  Any digit from 0 to 9
7) [a-zA-Z0-9]  Any alphanumeric character
8) [^a-zA-Z0-9] Except alphanumeric characters(Special Characters)

1) import re
2) matcher=re.finditer("x","a7b@k9z")
3) for match in matcher:
4) print(match.start(),". . ",match.group())

x = [abc] x = [^abc] x = [a-z] x = [0- x = [a-zA-Z0-9] x = [^a-zA-Z0-


9] 9]
0 ...... a 1 ...... 7 0 ...... a 1 ...... 7 0 ...... a 3 ...... @
2 ...... b 3 ...... @ 2 ...... b 5 ...... 9 1 ...... 7
4 .......k 4 ...... k 2 ...... b
5 ...... 9 6 ...... z 4 ...... k
6 ...... z 5 ...... 9
6 ...... z

KESA PAVAN KUMAR Cell No: 9848461833


189

Pre defined Character Classes:


1) \s  Space character
2) \S  Any character except space character
3) \d  Any digit from 0 to 9
4) \D  Any character except digit
5) \w  Any word character [a-zA-Z0-9]
6) \W  Any character except word character (Special Characters)
7) .  Any character including special characters

1) import re
2) matcher=re.finditer("x","a7b k@9z")
3) for match in matcher:
4) print(match.start(),". . ",match.group())
x = \s: x = \S: x = \d: x = \D: x = \w: x = \W: x=.
3 ...... 0 ...... a 1 ...... 7 0 ...... a 0 ...... a 3 ...... 0 ...... a
1 ...... 7 6 ...... 9 2 ...... b 1 ...... 7 5 ...... @ 1 ...... 7
2 ...... b 3 ...... 2.......b 2 ...... b
4 ...... k 4 ...... k 4.......k 3 ......
5 ...... @ 5 ...... @ 6 ...... 9 4 ...... k
6 ...... 9 7 ...... z 7.......z 5 ......
@
7 ...... z 6 ...... 9
7 ...... z

Qunatifiers:
We can use quantifiers to specify the number of occurrences to match.
1) a  Exactly one 'a'
2) a+  Atleast one 'a'
3) a*  Any number of a's including zero number
4) a?  Atmost one 'a' ie either zero number or one number
5) a{m}  Exactly m number of a's
6) a{m,n}  Minimum m number of a's and Maximum n number of a's.

1) import re
2) matcher=re.finditer("x","abaabaaab")
3) for match in
4) print(match.start(),". . ",match.group())
matcher:
x=
a?: x= x = a{2,4}:
0.......a a{3}: 2 ...... aa
x = a: x = a+: x = a*:
1 ...... 5 5
0 ...... a 0 ...... a 0 ...... a
2a ........ aa
2 ...... a 2 ...... aa 1 ...... ........ aa
3a a
3 ...... a 5 ...... aaa 2 ...... aa a
4 ......
5 ...... a 4 ...... 5a
6 ...... a 5 ...... aaa 6a
7 ...... a 8 ...... 7a
9 ...... 8 ......
9 ......

KESA PAVAN KUMAR Cell No: 9848461833


190

Note:
1) ^x  It will check whether target string starts with x OR not.
2) x$  It will check whether target string ends with x OR not.

Important Functions of Remodule:


1) match()
2) fullmatch()
3) search()
4) findall()
5) finditer()
6) sub()
7) subn()
8) split()
9) compile()

1) match():
 We can use match function to check the given pattern at beginning of target string.
 If the match is available then we will get Match object, otherwise we will get None.

1) import re
2) s=input("Enter pattern to check: ")
3) m=re.match(s,"abcabdefg")
4) if m!= None:
5) print("Match is available at the beginning of the String")
6) print("Start Index:",m.start(), "and End Index:",m.end())
7) else:
8) print("Match is not available at the beginning of the String")

Output:
D:\python_classes>py
test.py Enter pattern to
check: abc
Match is available at the beginning of the
String Start Index: 0 and End Index: 3

D:\python_classes>py
test.py Enter pattern to
check: bde
Match is not available at the beginning of the String

2) fullmatch():
 We can use fullmatch() function to match a pattern to all of target string.
i.e complete string should be matched according to given pattern.
 If complete string matched then this function returns Match object
otherwise it returns None.

KESA PAVAN KUMAR Cell No: 9848461833


191

1) import re
2) s=input("Enter pattern to check: ")
3) m=re.fullmatch(s,"ababab")
4) if m!= None:
5) print("Full String Matched")
6) else:
7) print("Full String not Matched")

Output:
D:\python_classes>py
test.py Enter pattern to
check: ab Full String not
Matched

D:\python_classes>py
test.py Enter pattern to
check: ababab Full String
Matched

3) search():
 We can use search() function to search the given pattern in the target string.
 If the match is available then it returns the Match object which
represents first occurrence of the match.
 If the match is not available then it returns None

1) import re
2) s=input("Enter pattern to check: ")
3) m=re.search(s,"abaaaba")
4) if m!= None:
5) print("Match is available")
6) print("First Occurrence of match with start index:",m.start(),"and end
index:",m.
end())
7) else:
8) print("Match is not available")

Output:
D:\python_classes>py
test.py Enter pattern to
check: aaa Match is
available
First Occurrence of match with start index: 2 and end index: 5

D:\python_classes>py
test.py Enter pattern to
check: bbb Match is not
available

KESA PAVAN KUMAR Cell No: 9848461833


192

4) findall():
 To find all occurrences of the match.
 This function returns a list object which contains all occurrences.

1) import re
2) l=re.findall("[0-9]","a7b9c5kz")
3) print(l)

Output: ['7', '9', '5']

5) finditer():
 Returns the iterator yielding a match object for each match.
 On each match object we can call start(), end() and group() functions.

1) import re
2) itr=re.finditer("[a-z]","a7b9c5k8z")
3) for m in itr:
4) print(m.start(),"...",m.end(),"...",m.group())

Output: D:\python_classes>py test.py


0 ... 1 ... a
2 ... 3 ... b
4 ... 5 ... c
6 ... 7 ... k
8 ... 9 ... z

6) sub():
 sub means substitution or replacement.
 re.sub(regex,replacement,targetstring)
 In the target string every matched pattern will be replaced with provided
replacement.

1) import re
2) s=re.sub("[a-z]","#","a7b9c5k8z")
3) print(s)

Output: #7#9#5#8#
Every alphabet symbol is replaced with # symbol

7) subn():
 It is exactly same as sub except it can also returns the number of replacements.
 This function returns a tuple where first element is result string and
second element is number of replacements.
(resultstring, number of replacements)

KESA PAVAN KUMAR Cell No: 9848461833


193

1) import re
2) t=re.subn("[a-z]","#","a7b9c5k8z")
3) print(t)
4) print("The Result String:",t[0])
5) print("The number of replacements:",t[1])

Output:
D:\python_classes>py
test.py ('#7#9#5#8#', 5)
The Result String:
#7#9#5#8# The number of
replacements: 5

8) split():
 If we want to split the given target string according to a particular
pattern then we should go for split() function.
 This function returns list of all tokens.

1) import re
2) l=re.split(",","sunny,bunny,chinny,vinny,pinny")
3) print(l)
4) for t in l:
5) print(t)

Output:
D:\python_classes>py test.py
['sunny', 'bunny', 'chinny', 'vinny',
'pinny'] sunny
bunn
y
chinn
y
vinny
pinny

1) import re
2) l=re.split("\.","www.durgasoft.com")
3) for t in l:
4) print(t)

Output:
D:\python_classes>py
test.py www
durgaso
ft com

KESA PAVAN KUMAR Cell No: 9848461833


194

9) ^ symbol:
 We can use ^ symbol to check whether the given target string starts with
our provided pattern or not.
 Eg: res = re.search("^Learn",s)
 If the target string starts with learn then it will return Match
object,otherwise returns None.

test.py
1) import re
2) s="Learning Python is Very Easy"
3) res=re.search("^Learn",s)
4) if res != None:
5) print("Target String starts with Learn")
6) else:
7) print("Target String Not starts with Learn")

Output: Target String starts with Learn

10) $ symbol:
 We can use $ symbol to check whether the given target string
ends with our provided pattern or not.
 Eg: res = re.search("Easy$",s)
 If the target string ends with Easy then it will return Match
object,otherwise returns None.

test.py
1) import re
2) s="Learning Python is Very Easy"
3) res=re.search("Easy$",s)
4) if res != None:
5) print("Target String ends with Easy")
6) else:
7) print("Target String Not ends with Easy")

Output: Target String ends with Easy

Note: If we want to ignore case then we have to pass 3rd argument


re.IGNORECASE for search() function.
Eg: res = re.search("easy$",s,re.IGNORECASE)

KESA PAVAN KUMAR Cell No: 9848461833


195

test.py
1) import re
2) s="Learning Python is Very Easy"
3) res=re.search("easy$",s,re.IGNORECASE)
4) if res != None:
5) print("Target String ends with Easy by ignoring case")
6) else:
7) print("Target String Not ends with Easy by ignoring case")

Output: Target String ends with Easy by ignoring case

App 1) Write a Regular Expression to represent


all Yava Language Identifiers
Rules:
1) The allowed characters are a-z,A-Z,0-9,#
2) The first character should be a lower case alphabet symbol from a to k
3) The second character should be a digit divisible by 3
4) The length of identifier should be atleast 2.
[a-k][0369][a-zA-Z0-9#]*

App 2) Write a Python Program to check whether


the given String is Yava Language Identifier
OR not?
1) import re
2) s=input("Enter Identifier:")
3) m=re.fullmatch("[a-k][0369][a-zA-Z0-9#]*",s)
4) if m!= None:
5) print(s,"is valid Yava Identifier")
6) else:
7) print(s,"is invalid Yava Identifier")

Output
D:\python_classes>py
test.py Enter
Identifier:a6kk9z##
a6kk9z## is valid Yava Identifier

D:\python_classes>py
test.py Enter
Identifier:k9b876 k9b876
is valid Yava Identifier
D:\python_classes>py
test.py Enter
Identifier:k7b9
k7b9 KESA
is invalid Yava Identifier
PAVAN KUMAR Cell No: 9848461833
196

App 3) Write a Regular Expression to represent all


10 Digit Mobile Numbers
Rules:
1) Every Number should contains exactly 10 Digits
2) The 1st Digit should be 7 OR 8 OR 9

[7-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-
9][0-9] OR
[7-9][0-
9]{9} OR
[7-9]\d{9}

App 4) Write a Python Program to check whether


the given Number is valid Mobile Number OR
not?
1) import re
2) n=input("Enter number:")
3) m=re.fullmatch("[7-9]\d{9}",n)
4) if m!= None:
5) print("Valid Mobile Number")
6) else:
7) print("Invalid Mobile Number")

Output
D:\python_classes>py
test.py Enter
number:9898989898 Valid
Mobile Number

D:\python_classes>py
test.py Enter
number:6786786787
Invalid Mobile Number

D:\python_classes>py
test.py Enter
number:898989
Invalid Mobile Number

App 5) Write a Python Program to extract all Mobile Numbers


present in input.txt where Numbers are mixed with
Normal Text Data
1) import re
2) f1=open("input.txt","r")
3) f2=open("output.txt","w")
KESA PAVAN KUMAR Cell No: 9848461833
197

4) for line in f1:


5) list=re.findall("[7-9]\d{9}",line)
6) for n in list:
7) f2.write(n+"\n")
8) print("Extracted all Mobile Numbers into output.txt")
9) f1.close()
10) f2.close()

Web Scraping by using Regular


Expressions
The process of collecting information from web pages is called web scraping.
In web scraping to match our required patterns like mail ids, mobile numbers
we can use regular expressions.

1) import re,urllib
2) import urllib.request
3) sites="google rediff".split()
4) print(sites)
5) for s in sites:
6) print("Searching...",s)
7) u=urllib.request.urlopen("http://"+s+".com")
8) text=u.read()
9) title=re.findall("<title>.*</title>",str(text),re.I)
10) print(title[0])

Program to get all Phone Numbers of redbus.in by using


Web Scraping and Regular Expressions
1) import re,urllib
2) import urllib.request
3) u=urllib.request.urlopen("https://www.redbus.in/info/contactus")
4) text=u.read()
5) numbers=re.findall("[0-9-]{7}[0-9-]+",str(text),re.I)
6) for n in numbers:
7) print(n)

Write a Python Program to check whether the given mail


id is valid gmail id OR not?
1) import re
2) s=input("Enter Mail id:")
3) m=re.fullmatch("\w[a-zA-Z0-9_.]*@gmail[.]com",s)
4) if m!=None:
5) print("Valid Mail Id");

KESA PAVAN KUMAR Cell No: 9848461833


198

6) else:
7) print("Invalid Mail id")

Output:
D:\python_classes>py test.py
Enter Mail
id:[email protected] Valid
Mail Id

D:\python_classes>py
test.py Enter Mail
id:durgatoc Invalid Mail
id

D:\python_classes>py test.py
Enter Mail
id:[email protected]
Invalid Mail id

Write a Python Program to check whether given Car


Registration Number is valid Telangana State Registration
Number OR not?
1) import re
2) s=input("Enter Vehicle Registration Number:")
3) m=re.fullmatch("TS[012][0-9][A-Z]{2}\d{4}",s)
4) if m!=None:
5) print("Valid Vehicle Registration Number");
6) else:
7) print("Invalid Vehicle Registration Number")

Output:
D:\python_classes>py test.py
Enter Vehicle Registration
Number:TS07EA7777 Valid Vehicle
Registration Number

D:\python_classes>py test.py
Enter Vehicle Registration
Number:TS07KF0786 Valid Vehicle
Registration Number

D:\python_classes>py test.py
Enter Vehicle Registration
Number:AP07EA7898 Invalid Vehicle
Registration Number

KESA PAVAN KUMAR Cell No: 9848461833


199

Python Program to check whether the given Mobile


Number is valid OR not (10 Digit OR 11 Digit OR 12 Digit)
1) import re
2) s=input("Enter Mobile Number:")
3) m=re.fullmatch("(0|91)?[7-9][0-9]{9}",s)
4) if m!=None:
5) print("Valid Mobile Number");
6) else:
7) print("Invalid Mobile Number")

Summary Table and some more Examples.

KESA PAVAN KUMAR Cell No: 9848461833


200

DECORATOR
FUNCTIONS

KESA PAVAN KUMAR Cell No: 9848461833


201

Decorator is a function which can take a function as argument and extend its
functionality and returns modified function with extended functionality.

Input new(add some functionality)


Function Decorator
inner()
wish()

Input Output Function


Function Decorat with extended
or Functionality
Functio
n
The main objective of decorator functions is we can extend the functionality
of existing functions without modifies that function.

1) def wish(name):
2) print("Hello",name,"Good Morning")

This function can always print same output for any name

Hello Durga Good


Morning Hello Ravi
Good Morning Hello
Sunny Good Morning

But we want to modify this function to provide different message if name


is Sunny. We can do this without touching wish() function by using
decorator.

1) def decor(func):
2) def inner(name):
3) if name=="Sunny":
4) print("Hello Sunny Bad Morning")
5) else:
6) func(name)
7) return inner
8)
9) @decor
10) def wish(name):
11) print("Hello",name,"Good Morning")
12)
13) wish("Durga")
14) wish("Ravi")
15) wish("Sunny")

Output
Hello Durga Good
Morning Hello Ravi
Good Morning

KESA PAVAN KUMAR Cell No: 9848461833


202

Hello Sunny Bad Morning


In the above program whenever we call wish() function automatically decor
function will be executed.

How to call Same Function with Decorator and without Decorator:


We should not use @decor

1) def decor(func):
2) def inner(name):
3) if name=="Sunny":
4) print("Hello Sunny Bad Morning")
5) else:
6) func(name)
7) return inner
8)
9) def wish(name):
10) print("Hello",name,"Good Morning")
11)
12) decorfunction=decor(wish)
13)
14) wish("Durga") #decorator wont be executed
15) wish("Sunny") #decorator wont be executed
16)
17) decorfunction("Durga")#decorator will be executed
18) decorfunction("Sunny")#decorator will be executed

Output
Hello Durga Good
Morning Hello Sunny
Good Morning Hello
Durga Good Morning
Hello Sunny Bad
Morning

1) def smart_division(func):
2) def inner(a,b):
3) print("We are dividing",a,"with",b)
4) if b==0:
5) print("OOPS...cannot divide")
6) return
7) else:
8) return func(a,b)
9) return inner
10)
11) @smart_division
12) def division(a,b):
13) return a/b

KESA PAVAN KUMAR Cell No: 9848461833


203

14) print(division(20,2))
15) print(division(20,0))

Without Decorator we will get Error. In this Case Output is:


10.0
Traceback (most recent call last):
File "test.py", line 16, in
<module>
print(division(20,0))
File "test.py", line 13, in
division return a/b
ZeroDivisionError: division by zero

With Decorator we won't get any Error. In this Case Output is:
We are dividing 20 with 2
10.0
We are dividing 20
with 0 OOPS...cannot
divide None

1) def marriagedecor(func):
2) def inner():
3) print('Hair decoration...')
4) print('Face decoration with Platinum
5) package')
print('Fair and Lovely
6) etc..')
func(
7) )
return inner
8)
9) def getready():
10) print('Ready for the marriage')
11)
12) decorated_getready=marriagedecor(getready)
13)
14) decorated_getready()

Decorator Chaining
We can define multiple decorators for the same function and all these
decorators will form Decorator Chaining.
Eg:
@decor1
@decor
def
num():

For num() function we are applying 2 decorator functions. First inner


decorator will work and then outer decorator.

KESA PAVAN KUMAR Cell No: 9848461833


204

1) def decor1(func):
2) def inner():
3) x=func()
4) return x*x
5) return inner
6)
7) def decor(func):
8) def inner():
9) x=func()
10) return 2*x
11) return inner
12)
13) @decor1
14) @decor
15) def num():
16) return 10
17)
18) print(num())

KESA PAVAN KUMAR Cell No: 9848461833


205

GENERATOR
FUNCTIONS

KESA PAVAN KUMAR Cell No: 9848461833


206

Generator is a function which is responsible to generate a sequence of values.


We can write generator functions just like ordinary functions, but it uses yield
keyword to return values.

Generator A Sequence of Values


Function
yield

1) def mygen():
2) yield 'A'
3) yield 'B'
4) yield 'C'
5)
6) g=mygen()
7) print(type(g))
8)
9) print(next(g))
10) print(next(g))
11) print(next(g))
12) print(next(g))

Output
<class
'generator'> A
B

C
Traceback (most recent call
last): File "test.py", line 12, in
<module> print(next(g))
StopIteration

1) def countdown(num):
2) print("Start Countdown")
3) while(num>0):
4) yield num
5) num=num-1
6) values=countdown(5)
7) for x in values:
8) print(x)

Output
Start
Countdown 5

KESA PAVAN KUMAR Cell No: 9848461833


207

4
3
2
1

Eg 3: To generate first n numbers


1) def firstn(num):
2) n=1
3) while n<=num:
4) yield n
5) n=n+1
6)
7) values=firstn(5)
8) for x in values:
9) print(x)

Output
1
2
3
4
5

We can convert generator into list as


follows: values = firstn(10)
l1 = list(values)
print(l1) #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Eg 4: To generate Fibonacci
Numbers... The next is the sum of
previous 2 numbers

Eg: 0,1,1,2,3,5,8,13,21,...
1) def fib():
2) a,b=0,1
3) while True:
4) yield a
5) a,b=b,a+b
6) for f in fib():
7) if f>100:
8) break
9) print(f)

KESA PAVAN KUMAR Cell No: 9848461833


208

Output
0
1
1
2
3
5
8
13
21
34
55
89

Advantages of Generator Functions:


1) When compared with Class Level Iterators, Generators are very easy to use.
2) Improves Memory Utilization and Performance.
3) Generators are best suitable for reading Data from Large Number of Large Files.
4) Generators work great for web scraping and crawling.

Generators vs Normal Collections wrt Performance:


1) import random
2) import time
3)
4) names = ['Sunny','Bunny','Chinny','Vinny']
5) subjects = ['Python','Java','Blockchain']
6)
7) def people_list(num_people):
8) results = []
9) for i in range(num_people):
10 person = {
)
11 'id':i,
)
12 'name': random.choice(names),
)
13 'subject':random.choice(subjects)
)
14 }
)
15 results.append(person)
)
16) return results
17)
18) def people_generator(num_people):
19) for i in range(num_people):
20 person = {
) KESA PAVAN KUMAR Cell No: 9848461833
209

21 'id':i,
)
22 'name': random.choice(names),
)

KESA PAVAN KUMAR Cell No: 9848461833


210

23 'major':random.choice(subj
)
24 } ects)
)25 yield
)26 person
)27) '''''t1 = time.clock()
28) people = people_list(10000000)
29) t2 = time.clock()'''
30
)31) t1 = time.clock()
32) people = people_generator(10000000)
33) t2 = time.clock()
34
35)
) print('Took {}'.format(t2-
t1))
Note: In the above program observe the differnce wrt execution time by
using list and generators

Generators vs Normal Collections wrt Memory Utilization:


Normal Collection:
l=[x*x for x in
range(10000000000000000)] print(l[0])

We will get MemoryError in this case because all these values are required to
store in the memory.

Generators:
g=(x*x for x in
range(10000000000000000))
print(next(g))

Output: 0

We won't get any MemoryError because the values won't be stored at the beginning

KESA PAVAN KUMAR Cell No: 9848461833


211

ASSERTIONS

KESA PAVAN KUMAR Cell No: 9848461833


212

Debugging Python Program by using assert


Keyword:
☕ The process of identifying and fixing the bug is called debugging.
☕ Very common way of debugging is to use print() statement. But the problem
with the print() statement is after fixing the bug,compulsory we have to
delete the extra added print() statments,otherwise these will be executed at
runtime which creates performance problems and disturbs console output.
☕ To overcome this problem we should go for assert statement. The main
advantage of assert statement over print() statement is after fixing bug we
are not required to delete assert statements. Based on our requirement we
can enable or disable assert statements.
☕ Hence the main purpose of assertions is to perform debugging. Usully we
can perform debugging either in development or in test environments but
not in production environment. Hence assertions concept is applicable
only for dev and test environments but not for production environment.

Types of assert Statements:


There are 2 types of assert statements
1) Simple Version
2) Augmented Version

1) Simple Version:
assert conditional_expression

2) Augmented Version:
 assert conditional_expression, message
 conditional_expression will be evaluated and if it is true then the
program will be continued.
 If it is false then the program will be terminated by raising AssertionError.
 By seeing AssertionError, programmer can analyze the code and can fix the
problem.

1) def squareIt(x):
2) return x**x
3) assert squareIt(2)==4,"The square of 2 should be 4"
4) assert squareIt(3)==9,"The square of 3 should be 9"
5) assert squareIt(4)==16,"The square of 4 should be 16"
6) print(squareIt(2))
7) print(squareIt(3))
8) print(squareIt(4))
9)
10) D:\Python_classes>py test.py
11) Traceback (most recent call last):
12) File "test.py", line 4, in <module>
13) assert squareIt(3)==9,"The square of 3 should be 9"

KESA PAVAN KUMAR Cell No: 9848461833


213

14) AssertionError: The square of 3 should be 9


15)
16) def squareIt(x):
17) return x*x
18) assert squareIt(2)==4,"The square of 2 should be 4"
19) assert squareIt(3)==9,"The square of 3 should be 9"
20) assert squareIt(4)==16,"The square of 4 should be 16"
21) print(squareIt(2))
22) print(squareIt(3))
23) print(squareIt(4))

Output
4
9
16

Exception Handling vs Assertions:


Assertions concept can be used to alert programmer to resolve development
time errors. Exception Handling can be used to handle runtime errors.

KESA PAVAN KUMAR Cell No: 9848461833


214

PYTHON
LOGGING

KESA PAVAN KUMAR Cell No: 9848461833


215

It is highly recommended to store complete application flow and exceptions


information to a file. This process is called logging.

The main advanatages of logging are:


1) We can use log files while performing debugging
2) We can provide statistics like number of requests

per day etc To implement logging, Python provides

inbuilt module logging.

Logging Levels:
Depending on type of information, logging data is divided according to the
following 6 levels in python

1) CRITICAL  50
Represents a very serious problem that needs high attention

2) ERROR  40
Represents a serious error

3) WARNING  30
Represents a warning message, some caution needed. It is alert to the programmer.

4) INFO  20
Represents a message with some important information

5) DEBUG  10
Represents a message with debugging information

6) NOTSET  0
Represents that level is not set

By default while executing Python program only WARNING and higher level
messages will be displayed.

How to implement Logging:


To perform logging, first we required to create a file to store messages and
we have to specify which level messages required to store.

We can do this by using basicConfig() function of


logging module.
logging.basicConfig(filename='log.txt',level=logging.WA
RNING)

The above line will create a file log.txt and we can store either WARNING level
or higher level messages to that file.

KESA PAVAN KUMAR Cell No: 9848461833


216

After creating log file, we can write messages to that file by using the following
methods
☕ logging.debug(message)
☕ logging.info(message)
☕ logging.warning(message)
☕ logging.error(message)
☕ logging.critical(message)

Q) Write a Python Program to create a Log File and write


WARNING and Higher Level Messages?
1) import logging
2) logging.basicConfig(filename='log.txt',level=logging.WARNING)
3) print('Logging Demo')
4) logging.debug('Debug Information')
5) logging.info('info Information')
6) logging.warning('warning Information')
7) logging.error('error Information')
8) logging.critical('critical Information')

log.txt:
WARNING:root:warning
Information ERROR:root:error
Information
CRITICAL:root:critical
Information

Note: In the above program only WARNING and higher level messages will
be written to the log file. If we set level as DEBUG then all messages will be
written to the log file.

test.py
1) import logging
2) logging.basicConfig(filename='log.txt',level=logging.DEBUG)
3) print('Logging Demo')
4) logging.debug('Debug Information')
5) logging.info('info Information')
6) logging.warning('warning Information')
7) logging.error('error Information')
8) logging.critical('critical Information')

log.txt
DEBUG:root:Debug Information
INFO:root:info Information
WARNING:root:warning
Information ERROR:root:error
Information
KESA PAVAN KUMAR Cell No: 9848461833
217

CRITICAL:root:critical
Information

KESA PAVAN KUMAR Cell No: 9848461833


218

How to configure Log File in over writing Mode:


In the above program by default data will be appended to the log file.i.e
append is the default mode. Instead of appending if we want to over write
data then we have to use filemode property.

logging.basicConfig(filename='log786.txt',level=logging.W
ARNING) Meant for appending

logging.basicConfig(filename='log786.txt',level=logging.WARNING,fil
emode='a') Explicitly we are specifying appending.

logging.basicConfig(filename='log786.txt',level=logging.WARNING,file
mode='w') Meant for over writing of previous data.

Note:
logging.basicConfig(filename='log.txt',level=logging.DEBUG)
If we are not specifying level then the default level is WARNING(30)
If we are not specifying file name then the messages will be printed to the console.

test.py
1) import logging
2) logging.basicConfig()
3) print('Logging Demo')
4) logging.debug('Debug Information')
5) logging.info('info Information')
6) logging.warning('warning Information')
7) logging.error('error Information')
8) logging.critical('critical Information')

D:\durgaclasses>py
test.py Logging Demo
WARNING:root:warning
Information ERROR:root:error
Information
CRITICAL:root:critical
Information

How to Format Log Messages:


By using format keyword argument, we can format messages.

1) To display only level name: logging.basicConfig(format='%(levelname)s')


Output
WARNIN
G
ERROR
CRITICA
L
KESA PAVAN KUMAR Cell No: 9848461833
219

2) To display levelname and message:


logging.basicConfig(format='%(levelname)s:%(me
ssage)s') Output
WARNING:warning
Information ERROR:error
Information
CRITICAL:critical
Information

How to add Timestamp in the Log Messages:


logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s')

Output
2018-06-15 11:50:08,325:WARNING:warning Information
2018-06-15 11:50:08,372:ERROR:error Information
2018-06-15 11:50:08,372:CRITICAL:critical Information

How to Change Date and Time Format:


We have to use special keyword argument: datefmt

logging.basicConfig(format='%(asctime)s:%(levelname)s:%(
message)s', datefmt='%d/%m/%Y %I:%M:%S %p')
datefmt='%d/%m/%Y %I:%M:%S %p'  Case is important

Output
15/06/2018 12:04:31 PM:WARNING:warning
Information 15/06/2018 12:04:31 PM:ERROR:error
Information 15/06/2018 12:04:31 PM:CRITICAL:critical
Information

Note:
%I  means 12 Hours time scale
%H  means 24 Hours time scale

Eg: logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s',
datefmt='%d/%m/%Y %H:%M:%S')

Output:
15/06/2018 12:06:28:WARNING:warning
Information 15/06/2018 12:06:28:ERROR:error
Information 15/06/2018 12:06:28:CRITICAL:critical
Information

https://docs.python.org/3/library/logging.html#logrecord-
attributes
https://docs.python.org/3/library/time.html#time.strftime

KESA PAVAN KUMAR Cell No: 9848461833


220

How to write Python Program Exceptions to the Log File:


By using the following function we can write exception information to the log file.
logging.exception(msg)

Q) Python Program to write Exception Information to the Log File


1) import logging
2) logging.basicConfig(filename='mylog.txt',level=logging.INFO,format='%(
asctime)s:
%(levelname)s:%(message)s',datefmt='%d/%m/%Y %I:%M:%S %p')
3) logging.info('A new Request Came')
4) try:

5)
6) x=int(input('Enter
y=int(input('Enter First
SecondNumber:'))
Number:'))
7) print('The Result:',x/y)
8)
9) except ZeroDivisionError as msg:
10) print('cannot divide with zero')
11) logging.exception(msg)
12
)13) except ValueError as msg:
14) print('Please provide int values only')
15) logging.exception(msg)
16
)17) logging.info('Request Processing Completed')

D:\durgaclasses>py
test.py Enter First
Number:10 Enter
Second Number:2 The
Result: 5.0

D:\durgaclasses>py
test.py Enter First
Number:20 Enter
Second Number:2 The
Result: 10.0

D:\durgaclasses>py
test.py Enter First
Number:10 Enter
Second Number:0
cannot divide with zero

D:\durgaclasses>py
test.py Enter First
Number:ten Please
provide int values only

KESA PAVAN KUMAR Cell No: 9848461833


221

mylog.txt
15/06/2018 12:30:51 PM:INFO:A new Request Came
15/06/2018 12:30:53 PM:INFO:Request Processing
Completed 15/06/2018 12:30:55 PM:INFO:A new
Request Came 15/06/2018 12:31:00 PM:INFO:Request
Processing Completed 15/06/2018 12:31:02 PM:INFO:A
new Request Came 15/06/2018 12:31:05
PM:ERROR:division by zero
Traceback (most recent call last):
File "test.py", line 7, in
<module> print('The
Result:',x/y)
ZeroDivisionError: division by zero
15/06/2018 12:31:05 PM:INFO:Request Processing
Completed 15/06/2018 12:31:06 PM:INFO:A new
Request Came
15/06/2018 12:31:10 PM:ERROR:invalid literal for int() with base 10:
'ten' Traceback (most recent call last):
File "test.py", line 5, in
<module> x=int(input('Enter
First Number:'))
ValueError: invalid literal for int() with base 10: 'ten'
15/06/2018 12:31:10 PM:INFO:Request Processing
Completed

Problems with Root Logger:


If we are not defining our own logger,then bydefault root logger will be
considered. Once we perform basic configuration to root logger then the
configurations are fixed and we cannot change.

Demo Application:
student.py:
1) import logging
2) logging.basicConfig(filename='student.log',level=logging.INFO)
3) logging.info('info message from student module')

test.py:
1) import logging
2) import student
3) logging.basicConfig(filename='test.log',level=logging.DEBUG)
4) logging.debug('debug message from test module')

student.log:
INFO: root:info message from student module

KESA PAVAN KUMAR Cell No: 9848461833


222

In the above application the configurations performed in test module won't be


reflected, because root logger is already configured in student module.

Need of Our Own Customized Logger:


The problems with root logger are:

1) Once we set basic configuration then that configuration is final and we cannot
change.
2) It will always work for only one handler at a time, either console or file,
but not both simultaneously.
3) It is not possible to configure logger with different configurations at different levels.
4) We cannot specify multiple log files for multiple modules/classes/methods.

To overcome these problems we should go for our own customized loggers

Advanced logging Module Features: Logger:


Logger is more advanced than basic logging.
It is highly recommended to use and it provides several extra features.

Steps for Advanced Logging:


1) Creation of Logger object and set
log level. logger =
logging.getLogger('demologger')
logger.setLevel(logging.INFO)

2) Creation of Handler object and set log level.

3) There are several types of Handlers like StreamHandler, FileHandler etc.


consoleHandler =
logging.StreamHandler()
consoleHandler.setLevel(logging.IN
FO)If we use StreamHandler then log messages will be printed to console.
Note:

4) Creation of Formatter Object.


formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s:
%(message)s', datefmt = '%d/%m/%Y %I:%M:%S %p')

5) Add Formatter to Handler  consoleHandler.setFormatter(formatter)

6) Add Handler to Logger  logger.addHandler(consoleHandler)

7) Write messages by using logger object and the following


methods logger.debug('debug message')
logger.info('info message')

KESA PAVAN KUMAR Cell No: 9848461833


223

logger.warn('warn
message')
logger.error('error
logger.critical('critical message')
message')
Note: Bydefault logger will set to WARNING level. But we can set our own
level based on our requirement.
logger = logging.getLogger('demologger')
logger.setLevel(logging.INFO)

logger log level by default available to console and file handlers. If we are
not satisfied with logger level, then we can set log level explicitly at
console level and file levels.

consoleHandler =
logging.StreamHandler()
consoleHandler.setLevel(logging.WAR
NING)
fileHandler =
logging.FileHandler('abc.log',mode='a')
fileHandler.setLevel(logging.ERROR)

Note: console and file log levels should be supported by logger. i.e logger log
level should be lower than console and file levels. Otherwise only logger log
level will be considered.

Eg:
logger  DEBUG console  INFO  Valid and INFO will be considered
logger  INFO console  DEBUG  Invalid and only INFO will be
considered to the console.

Demo Program for Console Handler:


1) import
logging
2) class LoggerDemoConsole:

3)
4) def testLog(self):
5) logger =
6) logging.getLogger('demologger')
logger.setLevel(logging.I
7) NFO)
8) consoleHandler =
9) logging.StreamHandler()
consoleHandler.setLevel(logging.
10 INFO)
)11) formatter = logging.Formatter('%(asctime)s -
%(name)s -
12 %(levelname)s: %(message)s',%I:%M:%S
datefmt='%m/%d/%Y
) %p')
13)
14 consoleHandler.setFormatter(form
)15 atter)
logger.addHandler(consoleHan
) dler)
KESA PAVAN KUMAR Cell No: 9848461833
224

16) logger.debug('debug message')


17) logger.info('info message')
18) logger.warn('warn message')
19) logger.error('error message')
20) logger.critical('critical message')
21)
22) demo = LoggerDemoConsole()
23) demo.testLog()

D:\durgaclasses>py loggingdemo3.py
06/18/2018 12:14:15 PM - demologger - INFO: info
message 06/18/2018 12:14:15 PM - demologger -
WARNING: warn message 06/18/2018 12:14:15 PM -
demologger - ERROR: error message 06/18/2018 12:14:15
PM - demologger - CRITICAL: critical message

Note: If we want to use class name as logger name then we have to create
logger object as follows logger = logging.getLogger(LoggerDemoConsole.
name )

In this case output is:

D:\durgaclasses>py loggingdemo3.py
06/18/2018 12:21:00 PM - LoggerDemoConsole - INFO: info
message 06/18/2018 12:21:00 PM - LoggerDemoConsole -
WARNING: warn message 06/18/2018 12:21:00 PM -
LoggerDemoConsole - ERROR: error message 06/18/2018 12:21:00
PM - LoggerDemoConsole - CRITICAL: critical message

Demo Program for File Handler:


1) import logging
2) class LoggerDemoConsole:
3)
4) def testLog(self):
5) logger = logging.getLogger('demologger')
6) logger.setLevel(logging.INFO)
7)
8) fileHandler = logging.FileHandler('abc.log',mode='a')
9) fileHandler.setLevel(logging.INFO)
10)
11 formatter = logging.Formatter('%(asctime)s - %(name)s -
)
%(levelname)s: %(message)s',
12 datefmt='%m/%d/%Y %I:%M:%S %p')
)
13)
14 fileHandler.setFormatter(formatter)
)
KESA PAVAN KUMAR Cell No: 9848461833
225

15 logger.addHandler(fileHandler)
)
16)

17 logger.debug('debug
)18 message')
logger.info('info
)19 message')
logger.warn('warn
)
20 message')
logger.error('error
)21 message')
logger.critical('critical
)22 message')
)23) demo =
LoggerDemoConsole()
24) demo.testLog()

abc.log:
07/05/2018 08:58:04 AM - demologger - INFO: info
message 07/05/2018 08:58:04 AM - demologger -
WARNING: warn message 07/05/2018 08:58:04 AM -
demologger - ERROR: error message 07/05/2018 08:58:04
AM - demologger - CRITICAL: critical message

Logger with Configuration File:


In the above program, everything we hard coded in the python script. It is not
a good programming practice. We will configure all the required things inside
a configuration file and we can use this file directly in our program.

logging.config.fileConfig('logging.conf')
logger = logging.getLogger(LoggerDemoConf. name )

Note: The extension of the file need not be conf. We can use any extension
like txt or durga etc.

logging.conf
[loggers]
keys=root,LoggerDemo
Conf

[handlers]
keys=fileHandl
er

[formatters]
keys=simpleFormat
ter

[logger_root]
level=DEBUG
handlers=fileHand
ler

KESA PAVAN KUMAR Cell No: 9848461833


226

[logger_LoggerDemoC
onf] level=DEBUG
handlers=fileHandler
qualname=demoLogge
r

[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormat
ter args=('test.log', 'w')

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s -
%(message)s datefmt=%m/%d/%Y %I:%M:%S %p

test.py

1) import logging
2) import logging.config
3) class
LoggerDemoConf():
4)
5) def testLog(self):
logging.config.fileConfig('logging.
6) conf')
logger = logging.getLogger(LoggerDemoConf.
7) name )
8) logger.debug('debug
9) message')
logger.info('info
10 message')
logger.warn('warn
)11 message')
logger.error('error
)12 message')
logger.critical('critical
)13 message')
)14) demo =
LoggerDemoConf()
15) demo.testLog()

test.log
06/18/2018 12:40:05 PM - LoggerDemoConf - DEBUG - debug
message 06/18/2018 12:40:05 PM - LoggerDemoConf - INFO -
info message 06/18/2018 12:40:05 PM - LoggerDemoConf -
WARNING - warn message 06/18/2018 12:40:05 PM -
LoggerDemoConf - ERROR - error message 06/18/2018
12:40:05 PM - LoggerDemoConf - CRITICAL - critical message

Case-1: To set log level as INFO


[handler_fileHandler]
class=FileHandler
level=INFO
formatter=simpleFormat
ter args=('test.log', 'w')

KESA PAVAN KUMAR Cell No: 9848461833


227

Case-2: To set Append Mode

[handler_fileHandler]
class=FileHandler
level=INFO
formatter=simpleFormat
ter args=('test.log', 'a')

Creation of Custom Logger:


customlogger.py
1) import logging
2) import inspect
3) def getCustomLogger(level):
4) # Get Name of class/method from where this method called
5) loggername=inspect.stack()[1][3]
6) logger=logging.getLogger(loggername)
7) logger.setLevel(level)
8)
9) fileHandler=logging.FileHandler('abc.log',mode='a')
10) fileHandler.setLevel(level)
11)
12) formatter = logging.Formatter('%(asctime)s - %(name)s -
%(levelname)s: %(message)s',datefmt='%m/%d/%Y %I:%M:%S %p')
13) fileHandler.setFormatter(formatter)
14) logger.addHandler(fileHandler)
15)
16) return logger

test.py
1) import logging
2) from customlogger import getCustomLogger
3) class LoggingDemo:
4) def m1(self):
5) logger=getCustomLogger(logging.DEBUG)
6) logger.debug('m1:debug message')
7) logger.info('m1:info message')
8) logger.warn('m1:warn message')
9) logger.error('m1:error message')
10 logger.critical('m1:critical message')
)
11 def m2(self):
)
12 logger=getCustomLogger(logging.WARNING)
)

KESA PAVAN KUMAR Cell No: 9848461833


228

13) logger.debug('m2:debug message')


14) logger.info('m2:info message')
15) logger.warn('m2:warn message')
16) logger.error('m2:error message')
17) logger.critical('m2:critical message')
18) def m3(self):
19) logger=getCustomLogger(logging.ERROR)
20) logger.debug('m3:debug message')
21) logger.info('m3:info message')
22) logger.warn('m3:warn message')
23) logger.error('m3:error message')
24) logger.critical('m3:critical message')
25)
26) l=LoggingDemo()
27) print('Custom Logger Demo')
28) l.m1()
29) l.m2()
30) l.m3()

abc.log:
06/19/2018 12:17:19 PM - m1 - DEBUG: m1:debug
message 06/19/2018 12:17:19 PM - m1 - INFO: m1:info
message 06/19/2018 12:17:19 PM - m1 - WARNING:
m1:warn message 06/19/2018 12:17:19 PM - m1 -
ERROR: m1:error message 06/19/2018 12:17:19 PM -
m1 - CRITICAL: m1:critical message 06/19/2018
12:17:19 PM - m2 - WARNING: m2:warn message
06/19/2018 12:17:19 PM - m2 - ERROR: m2:error
message 06/19/2018 12:17:19 PM - m2 - CRITICAL:
m2:critical message 06/19/2018 12:17:19 PM - m3 -
ERROR: m3:error message 06/19/2018 12:17:19 PM -
m3 - CRITICAL: m3:critical message

How to Create seperate Log File based on Caller:


1) import logging
2) import inspect
3) def getCustomLogger(level):
4) loggername=inspect.stack()[1][3]
5) logger=logging.getLogger(loggername)
6) logger.setLevel(level)
7)
8) fileHandler=logging.FileHandler('{}.log'.format(loggername),mode='a')
9) fileHandler.setLevel(level)
10)

KESA PAVAN KUMAR Cell No: 9848461833


229

11) formatter = logging.Formatter('%(asctime)s - %(name)s -


%(levelname)s: %(message)s',datefmt='%m/%d/%Y %I:%M:%S %p')
12) fileHandler.setFormatter(formatter)
13) logger.addHandler(fileHandler)
14
)15) return logger

test.py:
#Same as previous

1) import logging
2) from customlogger import getCustomLogger
3) class LoggingDemo:
4) def m1(self):
5) logger=getCustomLogger(logging.DEBUG)
6) logger.debug('m1:debug message')
7) logger.info('m1:info message')
8) logger.warn('m1:warn message')
9) logger.error('m1:error message')
10 logger.critical('m1:critical message')
)
11 def m2(self):
)
12 logger=getCustomLogger(logging.WARNING)
)
13 logger.debug('m2:debug message')
)
14 logger.info('m2:info message')
)
15 logger.warn('m2:warn message')
)
16 logger.error('m2:error message')
)
17 logger.critical('m2:critical message')
)
18 def m3(self):
)
19 logger=getCustomLogger(logging.ERROR)
)
20 logger.debug('m3:debug message')
)
21 logger.info('m3:info message')
)
22 logger.warn('m3:warn message')
)
23 logger.error('m3:error message')
)
24 logger.critical('m3:critical message')
)
25)
KESA PAVAN KUMAR Cell No: 9848461833
230

26) l=LoggingDemo()
27) print('Logging Demo with Seperate Log File')
28) l.m1()
29) l.m2()
30) l.m3()

m1.log
06/19/2018 12:26:04 PM - m1 - DEBUG: m1:debug
message 06/19/2018 12:26:04 PM - m1 - INFO: m1:info
message 06/19/2018 12:26:04 PM - m1 - WARNING:
m1:warn message

KESA PAVAN KUMAR Cell No: 9848461833


231

06/19/2018 12:26:04 PM - m1 - ERROR: m1:error


message 06/19/2018 12:26:04 PM - m1 - CRITICAL:
m1:critical message

m2.log
06/19/2018 12:26:04 PM - m2 - WARNING: m2:warn
message 06/19/2018 12:26:04 PM - m2 - ERROR:
m2:error message 06/19/2018 12:26:04 PM - m2 -
CRITICAL: m2:critical message

m3.log
06/19/2018 12:26:04 PM - m3 - ERROR: m3:error
message 06/19/2018 12:26:04 PM - m3 - CRITICAL:
m3:critical message

Advantages of Customized Logger:


1) We can reuse same customlogger code where ever logger required.
2) For every caller we can able to create a seperate log file
3) For different handlers we can set different log levels.

Another Example for Custom Handler:


customlogger.py:
1) import logging
2) import inspect
3) def getCustomLogger(level):
4) loggername=inspect.stack()[1][3]
5)
6) logger=logging.getLogger(loggername)
7) logger.setLevel(level)
8) fileHandler=logging.FileHandler('test.log',mode='a')
9) fileHandler.setLevel(level)
10) formatter=logging.Formatter('%(asctime)s - %(name)s -
%(levelname)s: %(message)s',datefmt='%m/%d/%Y %I:%M:%S %p')
11) fileHandler.setFormatter(formatter)
12) logger.addHandler(fileHandler)
13) return logger

test.py
1) import logging
2) from customlogger import getCustomLogger
3) class Test:
4) def logtest(self):
5) logger=getCustomLogger(logging.DEBUG)

KESA PAVAN KUMAR Cell No: 9848461833


232

6) logger.debug('debug message')
7) logger.info('info message')
8) logger.warning('warning message')
9) logger.error('error message')
10) logger.critical('critical message')
11) t=Test()
12) t.logtest()

student.py:
1) import logging
2) from customlogger import getCustomLogger
3) def studentfunction():
4) logger=getCustomLogger(logging.ERROR)
5) logger.debug('debug message')
6) logger.info('info message')
7) logger.warning('warning message')
8) logger.error('error message')
9) logger.critical('critical message')
10) studentfunction()

Note: we can disable a partcular level of logging as follows:


logging.disable(logging.CRITICAL)

KESA PAVAN KUMAR Cell No: 9848461833

You might also like