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

Module 4 Objects Classes

This document discusses classes and objects in Python. It defines a Point class to represent points on a coordinate system. The Point class has no members defined initially but attributes like x and y can be added to objects of this class. Functions like read_point(), print_point(), and distance() are defined to work with Point objects - reading attribute values from user, printing points, and calculating distance between two points. The program demonstrates creating Point objects, assigning attribute values, and calling functions to work with the objects.

Uploaded by

study material
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
129 views

Module 4 Objects Classes

This document discusses classes and objects in Python. It defines a Point class to represent points on a coordinate system. The Point class has no members defined initially but attributes like x and y can be added to objects of this class. Functions like read_point(), print_point(), and distance() are defined to work with Point objects - reading attribute values from user, printing points, and calculating distance between two points. The program demonstrates creating Point objects, assigning attribute values, and calling functions to work with the objects.

Uploaded by

study material
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 28

Python Application Programming

MODULE – 4
CLASSES AND OBJECTS
Python is an object-oriented programming language, and class is a basis for any object oriented
programming language. Class is a user-defined data type which binds data and functions together
into single entity. Class is just a prototype (or a logical entity/blue print) which will not consume any
memory. An object is an instance of a class and it has physical existence. One can create any number
of objects for a class. A class can have a set of variables (also known as attributes, member
variables) and member functions (also known as methods).

(Overview of general OOP concepts is given at the end of this module as an extra topic. Those who
are new to OOP concepts, it is suggested to have a glance and then continue reading).

Programmer-defined Types
A class in Python can be created using a keyword class. Here, we are creating an empty class
without any members by just using the keyword passwithin it.

class Point:
pass

print(Point)

The output would be –


<class ' main .Point'>

The term main indicates that the class Point is in the main scope of the current module. In other
words, this class is at the top level while executing the program.

Now, a user-defined data type Point got created, and this can be used to create any number of objects
of this class. Observe the following statements –

p=Point()

Now, a reference (for easy understanding, treat reference as a pointer) to Point object is created and
is returned. This returned reference is assigned to the object p. The process of creating a new object
is called as instantiation and the object is instance of a class. When we print an object, Python tells
which class it belongs to and where it is stored in the memory.
print(p)

The output would be –


< main .Point object at 0x003C1BF0>

Santosh Reddy P Page 1


Python Application Programming

The output displays the address (in hexadecimal format) of the object in the memory. It is now clear
that, the object occupies the physical space, whereas the class does not.

Attributes
An object can contain named elements known as attributes. One can assign values to these attributes
using dot operator. For example, keeping coordinate points in mind, we can assign two attributes x
and yfor the object pof a class Pointas below –

p.x =10.0
p.y =20.0

A state diagram that shows an object and its attributes is called as object diagram. For the object p,
the object diagram is shown in Figure 4.1.

Point
x 10.0
p
y 20.0

Figure 4.1 Object Diagram

The diagram indicates that a variable (i.e. object) p refers to a Point object, which contains two
attributes. Each attributes refers to a floating point number.

One can access attributes of an object as shown –

>>> print(p.x) 10.0


>>> print(p.y) 20.0

Here, p.x means “Go to the object p refers to and get the value of x”. Attributes of an object can
be assigned to other variables –

>>> x= p.x
>>> print(x)
10.0

Here, the variable x is nothing to do with attribute x. There will not be any name conflict between
normal program variable and attributes of an object.

A complete program: Write a class Point representing a point on coordinate system. Implement
following functions –
 A function read_point() to receive x and y attributes of a Point object as user input.

Santosh Reddy P Page 2


Python Application Programming

 A function distance() which takes two objects of Point class as arguments and computes the
Euclidean distance between them.
 A function print_point()to display one point in the form of ordered-pair.

import math class

Point:
""" This is a class Point representing a coordinate point
"""

def read_point(p):
p.x=float(input("x coordinate:"))
p.y=float(input("y coordinate:"))

def print_point(p): print("(%g,%g)"%(p.x,


p.y))

def distance(p1,p2):
d=math.sqrt((p1.x-p2.x)**2+(p1.y-p2.y)**2) return d

p1=Point() #create first object


print("Enter First point:")
read_point(p1) #read x and y for p1

p2=Point() #create second object


print("Enter Second point:")
read_point(p2) #read x and y for p2

dist=distance(p1,p2) #compute distance


print("First point is:")
print_point(p1) #print p1
print("Second point is:") print_point(p2) #print p2

print("Distance is: %g" %(distance(p1,p2))) #print d

The sample output of above program would be –


Enter First point: x
coordinate:10
y coordinate:20 Enter
Second point: x
coordinate:3
y coordinate:5
First point is: (10,20)

Santosh Reddy P Page 3


Python Application Programming

Second point is:(3,5) Distance


is: 16.5529

Let us discuss the working of above program thoroughly –


 The class Point contains a string enclosed within 3 double-quotes. This is known as
docstring. Usually, a string literal is written within 3 consecutive double-quotes inside a
class, module or function definition. It is an important part of documentation and is to help
someone to understand the purpose of the said class/module/function. The docstring becomes
a value for the special attribute viz. doc available for any class (and objects of that class).
To get the value of docstring associated with a class, one can use the statements like –

>>> print(Point. doc )


This is a class Point representing a coordinate point

>>> print(p1. doc )


This is a class Point representing a coordinate point

Note that, you need to type two underscores, then the word doc and again two underscores.

In the above program, there is no need of docstring and we would have just used pass to
indicate an empty class. But, it is better to understand the professional way of writing user-
defined types and hence, introduced docstring.

 The function read_point() take one argument of type Point object. When we use the
statements like,
read_point(p1)

the parameter p of this function will act as an alias for the argument p1. Hence, the
modification done to the alias p reflects the original argument p1. With the help of this
function, we are instructing Python that the object p1 has two attributes x and y.

 The function print_point() also takes one argument and with the help of format- strings, we
are printing the attributes x and y of the Point object as an ordered-pair (x,y).

 As we know, the Euclidean distance between two points (x1,y1) and (x2,y2) is
x1  x22   y1  y2 2
In this program, we have Point objects as (p1.x, p1.y) and (p2.x, p2.y). Apply the formula on
these points by passing objects p1 and p2 as parameters to the function distance(). And then
return the result.

Santosh Reddy P Page 4


Python Application Programming

Thus, the above program gives an idea of defining a class, instantiating objects, creating attributes,
defining functions that takes objects as arguments and finally, calling (or invoking) such functions
whenever and wherever necessary.

NOTE: User-defined classes in Python have two types of attributes viz. class attributes and
instance attributes. Class attributes are defined inside the class (usually, immediately after class
header). They are common to all the objects of that class. That is, they are shared by all the objects
created from that class. But, instance attributes defined for individual objects. They are available
only for that instance (or object). Attributes of one instance are not available for another instance of
the same class. For example, consider the class Point as discussed earlier –

class Point:
pass

p1= Point() #first object of the class


p1.x=10.0 #attributes for p1
p1.y=20.0
print(p1.x, p1.y) #prints 10.0 20.0

p2= Point() #second object of the class


print(p2.x) #displays error as below

AttributeError: 'Point' object has no attribute 'x'

This clearly indicates that the attributes x and y created are available only for the object p1, but not
for p2. Thus, x and y are instance attributes but not class attributes.

We will discuss class attributes late in-detail. But, for the understanding purpose, observe the
following example –

class Point: x=2


y=3

p1=Point() #first object of the class


print(p1.x, p1.y) # prints 2 3

p2=Point() #second object of the class


print(p2.x, p2.y) # prints 2 3

Here, the attributes x and y are defined inside the definition of the class Point itself. Hence, they are
available to all the objects of that class.

Santosh Reddy P Page 5


Python Application Programming

Rectangles
It is possible to make an object of one class as an attribute to other class. To illustrate this, consider
an example of creating a class called as Rectangle. A rectangle can be created using any of the
following data –
 By knowing width and height of a rectangle and one corner point (ideally, a bottom- left
corner) in a coordinate system
 By knowing two opposite corner points
Let us consider the first technique and implement the task: Write a class Rectangle containing
numeric attributes width and height. This class should contain another attribute corner which is an
instance of another class Point. Implement following functions –
 A function to print corner point as an ordered-pair
 A function find_center() to compute center point of the rectangle
 A function resize() to modify the size of rectangle

The program is as given below –

class Point:
""" This is a class Point representing coordinate
point
"""

class Rectangle:
""" This is a class Rectangle.
Attributes: width, height and Corner Point """

def find_center(rect): p=Point()


p.x = rect.corner.x + rect.width/2
p.y = rect.corner.y + rect.height/2 return p

def resize(rect, w, h): rect.width


+=w rect.height +=h

def print_point(p): print("(%g,%g)"%(p.x,


p.y))

box=Rectangle() #create Rectangle object box.corner=Point()


#define an attribute corner for box box.width=100
#set attribute width to box
box.height=200 #set attribute height to box box.corner.x=0 #corner itself has
two attributes x and y box.corner.y=0#initialize x and y to 0

Santosh Reddy P Page 6


Python Application Programming

print("Original Rectangle is:")


print("width=%g, height=%g"%(box.width, box.height))

center=find_center(box)
print("The center of rectangle is:") print_point(center)

resize(box,50,70) print("Rectangle after


resize:")
print("width=%g, height=%g"%(box.width, box.height))

center=find_center(box)
print("The center of resized rectangle is:") print_point(center)

A sample output would be:


Original Rectangle is: width=100, height=200 The center of
rectangle is: (50,100) Rectangle after resize: width=150,
height=270 The center of resized rectangle is: (75,135)

The working of above program is explained in detail here –


 Two classes Pointand Rectanglehave been created with suitable docstrings. As of now, they
do not contain any class-level attributes.
 The following statement instantiates an object of Rectangleclass.
box=Rectangle()

The statement
box.corner=Point()
indicates that corner is an attribute for the object box and this attribute itself is an object of
the class Point. The following statements indicate that the object box has two more attributes

box.width=100 #give any numeric value
box.height=200 #give any numeric value

In this program, we are treating the corner point as the origin in coordinate system and hence
the following assignments –
box.corner.x=0 box.corner.y=0

(Note that, instead of origin, any other location in the coordinate system can be given as
corner point.)

Based on all above statements, an object diagram can be drawn as –

Santosh Reddy P Page 7


Python Application Programming

Rectangle

box width 100 Point


height 200
x 0
corner y 0

The expression box.corner.x means, “Go to the object box refers to and select the attribute
named corner; then go to that object and select the attribute named x.”

 The function find_center() takes an object rect as an argument. So, when a call is made using
the statement –

center=find_center(box)

the object rect acts as an alias for the argument box.

A local object p of type Point has been created inside this function. The attributes of p are x
and y, which takes the values as the coordinates of center point of rectangle. Center of a
rectangle can be computed with the help of following diagram.

Half of height (x+ half of width, y+ half of height)

(x,y)
Half of width

The function find_center() returns the computed center point. Note that, the return value of a
function here is an instance of some class. That is, one can have an instance as return values
from a function.

 The function resize() takes three arguments: rect – an instance of Rectangle class and two
numeric variables w and h. The values w and h are added to existing attributes width and
height. This clearly shows that objects are mutable. State of an object can be changed by
modifying any of its attributes. When this function is called with a statement –
resize(box,50,70)
the rect acts as an alias for box. Hence, width and height modified within the function will
reflect the original object box.

Santosh Reddy P Page 8


Python Application Programming

Thus, the above program illustrates the concepts: object of one class is made as attribute for object
of another class, returning objects from functions and objects are mutable.

Copying
An object will be aliased whenever there an object is assigned to another object of same class. This
may happen in following situations –
 Direct object assignment (like p2=p1)
 When an object is passed as an argument to a function
 When an object is returned from a function

The last two cases have been understood from the two programs in previous sections. Let us
understand the concept of aliasing more in detail using the following program –
>>> class Point:
pass

>>> p1=Point()
>>> p1.x=10
>>> p1.y=20
>>> p2=p1
>>> print(p1)
< main .Point object at 0x01581BF0>
>>> print(p2)
< main .Point object at 0x01581BF0>

Observe that both p1 and p2 objects have same physical memory. It is clear now that the object p2 is
an alias for p1. So, we can draw the object diagram as below –

p1 x 10 p2
y 20

Hence, if we check for equality and identity of these two objects, we will get following result.

>>> p1 is p2
True
>>> p1==p2
True

But, the aliasing is not good always. For example, we may need to create a new object using an
existing object such that – the new object should have a different physical memory, but it must have
same attribute (and their values) as that of existing object. Diagrammatically, we need something as
below –

Santosh Reddy P Page 9


Python Application Programming

x 10 x 10
p1 p2
y 20 y 20

In short, we need a copy of an object, but not an alias. To do this, Python provides a module called
copy and a method called copy(). Consider the below given program to understand the concept.

>>> class Point:


pass

>>> p1=Point()
>>> p1.x=10
>>> p1.y=20

>>> import copy #import module copy


>>> p3=copy.copy(p1) #use the method copy()
>>> print(p1)
< main .Point object at 0x01581BF0>
>>> print(p3)
< main .Point object at 0x02344A50>
>>> print(p3.x,p3.y) 10 20

Observe that the physical address of the objects p1 and p3 are now different. But, values of attributes
xand yare same. Now, use the following statements –

>>> p1 is p3
False
>>> p1 == p3
False

Here, the is operator gives the result as False for the obvious reason of p1 and p3 are being two
different entities on the memory. But, why == operator is generating False as the result, though the
contents of two objects are same? The reason is – p1 and p3 are the objects of user-defined type.
And, Python cannot understand the meaning of equality on the new data type. The default behavior
of equality (==) is identity (is operator) itself. Hence, Python applies this default behavior on p1 ==
p3and results in False.

(NOTE: If we need to define the meaning of equality (==) operator explicitly on user-defined data
types (i.e. on class objects), then we need to override the method eq () inside the class. This will be
discussed later in detail.)

Santosh Reddy P Page 10


Python Application Programming

The copy() method of copy module duplicates the object. The content (i.e. attributes) of one object is
copied into another object as we have discussed till now. But, when an object itself is an attribute
inside another object, the duplication will result in a strange manner. To understand this concept, try
to copy Rectangle object (created in previous section) as given below –

import copy class


Point:
""" This is a class Point representing coordinate
point
"""

class Rectangle:
""" This is a class Rectangle.
Attributes: width, height and Corner Point """

box1=Rectangle()
box1.corner=Point()
box1.width=100
box1.height=200
box1.corner.x=0
box1.corner.y=0

box2=copy.copy(box1)
print(box1 is box2) #prints False
print(box1.corner is box2.corner) #prints True

Now, the question is – why box1.corner and box2.corner are same objects, when
box1 and box2 are different? Whenever the statement

box2=copy.copy(box1)

is executed, the contents of all the attributes of box1 object are copied into the respective attributes
of box2 object. That is, box1.width is copied into box2.width, box1.height is copied into
box2.height. Similarly, box1.corner is copied into box2.corner. Now, recollect the fact that corner is
not exactly the object itself, but it is a reference to the object of type Point (Read the discussion done
for Figure 4.1 at the beginning of this Chapter). Hence, the value of reference (that is, the physical
address) stored in box1.corner is copied into box2.corner. Thus, the physical object to which
box1.corner and box2.corner are pointing is only one. This type of copying the objects is known as
shallow copy. To understand this behavior, observe the following diagram –

Santosh Reddy P Page 11


Python Application Programming

Rectangle Rectangle

box1 width 100 width 100 box2


height 200 Point
height 200
x 0
corner y 0 corner

Now, the attributes width and height for two objects box1 and box2 are independent. Whereas, the
attribute corner is shared by both the objects. Thus, any modification done to box1.corner will reflect
box2.corner as well. Obviously, we don’t want this to happen, whenever we create duplicate objects.
That is, we want two independent physical objects. Python provides a method deepcopy() for doing
this task. This method copies not only the object but also the objects it refers to, and the objects they
refer to, and so on.

box3=copy.deepcopy(box1)
print(box1 is box3) #prints False
print(box1.corner is box3.corner) #prints False

Thus, the objects box1 and box3 are now completely independent.

Debugging
While dealing with classes and objects, we may encounter different types of errors. For example, if
we try to access an attribute which is not there for the object, we will get AttributeError. For
example –

>>> p= Point()
>>> p.x = 10
>>> p.y = 20
>>> print(p.z)
AttributeError: 'Point' object has no attribute 'z'

To avoid such error, it is better to enclose such codes within try/except as given below –
try:
z = p.x
except AttributeError: z = 0

When we are not sure, which type of object it is, then we can use type() as –
>>> type(box1)
<class ' main .Rectangle'>

Santosh Reddy P Page 12


Python Application Programming

Another method isinstance() helps to check whether an object is an instance of a particular class –
>>> isinstance(box1,Rectangle) True

When we are not sure whether an object has a particular attribute or not, use a function
hasattr() –
>>> hasattr(box1, 'width') True

Observe the string notation for second argument of the function hasattr(). Though the attribute width
is basically numeric, while giving it as an argument to function hasattr(), it must be enclosed within
quotes.

CLASSES AND FUNCTIONS


Though Python is object oriented programming languages, it is possible to use it as functional
programming. There are two types of functions viz. pure functions and modifiers. A pure function
takes objects as arguments and does some work without modifying any of the original argument. On
the other hand, as the name suggests, modifier function modifies the original argument.

In practical applications, the development of a program will follow a technique called as prototype
and patch. That is, solution to a complex problem starts with simple prototype and incrementally
dealing with the complications.

Pure Functions
To understand the concept of pure functions, let us consider an example of creating a class called
Time. An object of class Time contains hour, minutes and seconds as attributes. Write a function to
print time in HH:MM:SS format and another function to add two time objects. Note that, adding two
time objects should yield proper result and hence we need to check whether number of seconds
exceeds 60, minutes exceeds 60 etc, and take appropriate action.

class Time:
"""Represents the time of a day Attributes: hour,
minute, second """

def printTime(t): print("%.2d:%.2d:%.2d"%(t.hour,t.minute,t.second))

def add_time(t1,t2):
sum=Time()
sum.hour = t1.hour + t2.hour sum.minute =
t1.minute + t2.minute sum.second = t1.second +
t2.second

Santosh Reddy P Page 13


Python Application Programming

if sum.second >= 60:


sum.second -= 60
sum.minute += 1 if
sum.minute >= 60:
sum.minute -= 60
sum.hour += 1

return sum

t1=Time() t1.hour=10
t1.minute=34
t1.second=25 print("Time1
is:") printTime(t1)

t2=Time() t2.hour=2
t2.minute=12
t2.second=41
print("Time2 is :")
printTime(t2)

t3=add_time(t1,t2)
print("After adding two time objects:") printTime(t3)

The output of this program would be –


Time1 is: 10:34:25
Time2 is : 02:12:41
After adding two time objects: 12:47:06

Here, the function add_time() takes two arguments of type Time, and returns a Time object,
whereas, it is not modifying contents of its arguments t1 and t2. Such functions are called as pure
functions.

Modifiers
Sometimes, it is necessary to modify the underlying argument so as to reflect the caller. That is,
arguments have to be modified inside a function and these modifications should be available to the
caller. The functions that perform such modifications are known as modifier function. Assume that,
we need to add few seconds to a time object, and get a new time. Then, we can write a function as
below –

Santosh Reddy P Page 14


Python Application Programming

def increment(t, seconds): t.second +=


seconds

while t.second >= 60: t.second


-= 60
t.minute += 1

while t.minute >= 60: t.minute


-= 60
t.hour += 1

In this function, we will initially add the argument seconds to t.second. Now, there is a chance that
t.second is exceeding 60. So, we will increment minute counter till t.second becomes lesser than 60.
Similarly, till the t.minute becomes lesser than 60, we will decrement minute counter. Note that, the
modification is done on the argument t itself. Thus, the above function is a modifier.

Prototyping v/s Planning


Whenever we do not know the complete problem statement, we may write the program initially, and
then keep of modifying it as and when requirement (problem definition) changes. This methodology
is known as prototype and patch. That is, first design the prototype based on the information
available and then perform patch-work as and when extra information is gathered. But, this type of
incremental development may end-up in unnecessary code, with many special cases and it may be
unreliable too.

An alternative is designed development, in which high-level insight into the problem can make the
programming much easier. For example, if we consider the problem of adding two time objects,
adding seconds to time object etc. as a problem involving numbers with base 60 (as every hour is 60
minutes and every minute is 60 seconds), then our code can be improved. Such improved versions
are discussed later in this chapter.

Debugging
In the program written in Section 4.2.1, we have treated time objects as valid values. But, what if the
attributes (second, minute, hour) of time object are given as wrong values like negative number, or
hours with value more than 24, minutes/seconds with more than 60 etc? So, it is better to write error-
conditions in such situations to verify the input. We can write a function similar to as given below –

def valid_time(time):
if time.hour < 0 or time.minute < 0 or time.second < 0: return False

if time.minute >= 60 or time.second >= 60: return False

return True

Santosh Reddy P Page 15


Python Application Programming

Now, at the beginning of add_time()function, we can put a condition as –

def add_time(t1, t2):


if not valid_time(t1) or not valid_time(t2):
raise ValueError('invalid Time object in add_time') #remaining statements of

add_time() functions

Python provides another debugging statement assert. When this keyword is used, Python evaluates
the statement following it. If the statement is True, further statements will be evaluated sequentially.
But, if the statement is False, then AssertionError exception is raised. The usage of assert is shown
here –

def add_time(t1, t2):


assert valid_time(t1) and valid_time(t2) #remaining statements of
add_time() functions
The assert statement clearly distinguishes the normal conditional statements as a part of the logic of
the program and the code that checks for errors.

CLASSES AND METHODS


The classes that have been considered till now were just empty classes without having any
definition. But, in a true object oriented programming, a class contains class-level attributes,
instance-level attributes, methods etc. There will be a tight relationship between the object of the
class and the function that operate on those objects. Hence, the object oriented nature of Python
classes will be discussed here.

Object-Oriented Features
As an object oriented programming language, Python possess following characteristics:
 Programs include class and method definitions.
 Most of the computation is expressed in terms of operations on objects.
 Objects often represent things in the real world, and methods often correspond to the ways
objects in the real world interact.

To establish relationship between the object of the class and a function, we must define a function as
a member of the class. A function which is associated with a particular class is known as a method.
Methods are semantically the same as functions, but there are two syntactic differences:
 Methods are defined inside a class definition in order to make the relationship between the
class and the method explicit.
 The syntax for invoking a method is different from the syntax for calling a function.

Now onwards, we will discuss about classes and methods.

Santosh Reddy P Page 16


Python Application Programming

The __init () Method


(A method init () has to be written with two underscores before and after the word init)

Python provides a special method called as init () which is similar to constructor method in other
programming languages like C++/Java. The term init indicates initialization. As the name suggests,
this method is invoked automatically when the object of a class is created. Consider the example
given here –

import math class

Point:
def init (self,a,b): self.x=a
self.y=b

def dist(self,p2):
d=math.sqrt((self.x-p2.x)**2 + (self.y-p2.y)**2) return d

def str (self):


return "(%d,%d)"%(self.x, self.y)

p1=Point(10,20) # init () is called automatically p2=Point(4,5)


# init () is called automatically

print("P1 is:",p1) # str () is called automatically print("P2 is:",p2)


# str () is called automatically

d=p1.dist(p2) #explicit call for dist() print("The

distance is:",d)

The sample output is –


P1 is: (10,20)
P2 is: (4,5)
Distance is: 16.15549442140351

Let us understand the working of this program and the concepts involved:
 Keep in mind that every method of any class must have the first argument as self. The
argument self is a reference to the current object. That is, it is reference to the object which
invoked the method. (Those who know C++, can relate self with this pointer). The object
which invokes a method is also known as subject.

 The method init () inside the class is an initialization method, which will be invoked
automatically when the object gets created. When the statement like –

Santosh Reddy P Page 17


Python Application Programming

p1=Point(10,20)

is used, the init () method will be called automatically. The internal meaning of the above
line is –
p1. init (10,20)

Here, p1 is the object which is invoking a method. Hence, reference to this object is created
and passed to init () as self. The values 10 and 20 are passed to formal parameters a and b of
init () method. Now, inside init () method, we have statements

self.x=10
self.y=20

This indicates, x and y are instance attributes. The value of x for the object p1 is 10 and, the
value of yfor the object p1is 20.

When we create another object p2, it will have its own set of x and y. That is, memory
locations of instance attributes are different for every object.

Thus, state of the object can be understood by instance attributes.

 The method dist() is an ordinary member method of the class Point. As mentioned earlier, its
first argument must be self. Thus, when we make a call as –

d=p1.dist(p2)

a reference to the object p1 is passed as self to dist() method and p2 is passed explicitly as a
second argument. Now, inside the dist()method, we are calculating distance between two
point (Euclidian distance formula is used) objects. Note that, in this method, we cannot use
the name p1, instead we will use self which is a reference (alias) to p1.

 The next method inside the class is str (). It is a special method used for string
representation of user-defined object. Usually, print() is used for printing basic types in
Python. But, user-defined types (class objects) have their own meaning and a way of
representation. To display such types, we can write functions or methods like print_point() as
we did in Section 4.1.2. But, more polymorphic way is to use str () so that, when we write
just print() in the main part of the program, the str () method will be invoked automatically.
Thus, when we use the statement like –
print("P1 is:",p1)

the ordinary print() method will print the portion “P1 is:” and the remaining portion is taken
care by str () method. In fact, str () method will return the string

Santosh Reddy P Page 18


Python Application Programming

format what we have given inside it, and that string will be printed by print()
method.

Operator Overloading
Ability of an existing operator to work on user-defined data type (class) is known as operator
overloading. It is a polymorphic nature of any object oriented programming. Basic operators like +, -
, * etc. can be overloaded. To overload an operator, one needs to write a method within user-defined
class. Python provides a special set of methods which have to be used for overloading required
operator. The method should consist of the code what the programmer is willing to do with the
operator. Following table shows gives a list of operators and their respective Python methods for
overloading.

Operator Special Function Operator Special Function


in Python in Python

+ add () <= le ()

- sub () >= ge ()

* mul () == eq ()

/ truediv () != ne ()

% mod () in contains ()

< lt () len len ()

> gt () str str ()

Let us consider an example of Point class considered earlier. Using operator overloading, we can try
to add two point objects. Consider the program given below –

class Point:
def init (self,a=0,b=0): self.x=a
self.y=b

def add (self, p2): p3=Point()


p3.x=self.x+p2.x
p3.y=self.y+p2.y return p3

def str (self):


return "(%d,%d)"%(self.x, self.y)

Santosh Reddy P Page 19


Python Application Programming

p1=Point(10,20)
p2=Point(4,5) print("P1
is:",p1)
print("P2 is:",p2)
p4=p1+p2 #call for add () method print("Sum
is:",p4)

The output would be –


P1 is: (10,20)
P2 is: (4,5)
Sum is: (14,25)

In the above program, when the statement p4 = p1+p2 is used, it invokes a special method add ()
written inside the class. Because, internal meaning of this statement is–
p4 = p1. add (p4)

Here, p1 is the object invoking the method. Hence, self inside add () is the reference (alias) of p1.
And, p4 is passed as argument explicitly.

In the definition of add (), we are creating an object p3with the statement –
p3=Point()

The object p3 is created without initialization. Whenever we need to create an object with and
without initialization in the same program, we must set arguments of init () for some default values.
Hence, in the above program arguments a and b of init () are made as default arguments with values
as zero. Thus, x and y attributes of p3 will be now zero. In the add () method, we are adding
respective attributes of self and p2 and storing in p3.x and p3.y. Then the object p3 is returned. This
returned object is received as p4and is printed.

NOTE that, in a program containing operator overloading, the overloaded operator behaves in a
normal way when basic types are given. That is, in the above program, if we use the statements
m= 3+4
print(m)

it will be usual addition and gives the result as 7. But, when user-defined types are used as operands,
then the overloaded method is invoked.

Let us consider a more complicated program involving overloading. Consider a problem of creating
a class called Time, adding two Time objects, adding a number to Time object etc. that we had
considered in previous section. Here is a complete program with more of OOP concepts.

Santosh Reddy P Page 20


Python Application Programming

class Time:
def init (self, h=0,m=0,s=0): self.hour=h
self.min=m
self.sec=s

def time_to_int(self):
minute=self.hour*60+self.min
seconds=minute*60+self.sec return
seconds

def int_to_time(self, seconds): t=Time()


minutes, t.sec=divmod(seconds,60) t.hour,
t.min=divmod(minutes,60) return t

def str (self):


return "%.2d:%.2d:%.2d"%(self.hour,self.min,self.sec)

def eq (self,t):
return self.hour==t.hour and self.min==t.min and self.sec==t.sec

def add (self,t):


if isinstance(t, Time): return
self.addTime(t)
else:
return self.increment(t)

def addTime(self, t): seconds=self.time_to_int()+t.time_to_int() return


self.int_to_time(seconds)

def increment(self, seconds): seconds +=


self.time_to_int() return
self.int_to_time(seconds)

def radd (self,t): return self. add (t)

T1=Time(3,40) T2=Time(5,45)
print("T1 is:",T1)
print("T2 is:",T2)
print("Whether T1 is same as T2?",T1==T2) #call for eq () T3=T1+T2 #call for add ()

Santosh Reddy P Page 21


Python Application Programming

print("T1+T2 is:",T3)

T4=T1+75 #call for add ()


print("T1+75=",T4)

T5=130+T1 #call for radd ()


print("130+T1=",T5)

T6=sum([T1,T2,T3,T4])
print("Using sum([T1,T2,T3,T4]):",T6)

The output would be –


T1 is: 03:40:00
T2 is: 05:45:00
Whether T1 is same as T2? False T1+T2 is:
09:25:00
T1+75= 03:41:15
130+T1= 03:42:10
Using sum([T1,T2,T3,T4]): 22:31:15

Working of above program is explained hereunder –


 The class Time has init () method for initialization of instance attributes
hour, minand sec. The default values of all these are being zero.
 The method time_to_int() is used convert a Time object (hours, min and sec) into single
integer representing time in number of seconds.
 The method int_to_time() is written to convert the argument seconds into time object in the
form of hours, min and sec. The built-in method divmod() gives the quotient as well as
remainder after dividing first argument by second argument given to it.
 Special method eq ()is for overloading equality (==) operator. We can say one Time object is
equal to the other Time object if underlying hours, minutes and seconds are equal
respectively. Thus, we are comparing these instance attributes individually and returning
either True of False.
 When we try to perform addition, there are 3 cases –
o Adding two time objects like T3=T1+T2.
o Adding integer to Time object like T4=T1+75
o Adding Time object to an integer like T5=130+T1

Each of these cases requires different logic. When first two cases are considered, the first
argument will be T1 and hence self will be created and passed to
add () method. Inside this method, we will check the type of second argument using
isinstance() method. If the second argument is Time object, then we call addTime() method.
In this method, we will first convert both Time objects to integer (seconds) and then the
resulting sum into Time object again. So, we make use time_to_int() and int_to_time() here.
When the 2nd argument is an integer,

Santosh Reddy P Page 22


Python Application Programming

it is obvious that it is number of seconds. Hence, we need to call increment()


method.

Thus, based on the type of argument received in a method, we take appropriate action. This is
known as type-based dispatch.

In the 3rd case like T5=130+T1, Python tries to convert first argument 130 into self, which is
not possible. Hence, there will be an error. This indicates that for Python, T1+5 is not same
as 5+T1 (Commutative law doesn’t hold good!!). To avoid the possible error, we need to
implement right-side addition method radd (). Inside this method, we can call overloaded
method add ().
 The beauty of Python lies in surprising the programmer with more facilities!! As we have
implemented add () method (that is, overloading of + operator), the built- in sum() will is
capable of adding multiple objects given in a sequence. This is due to Polymorphism in
Python. Consider a list containing Time objects, and then call sum()on that list as –

T6=sum([T1,T2,T3,T4])

The sum() internally calls add () method multiple times and hence gives the appropriate
result. Note down the square-brackets used to combine Time objects as a list and then
passing it to sum().

Thus, the program given here depicts many features of OOP concepts.

Debugging
We have seen earlier that hasattr() method can be used to check whether an object has particular
attribute. There is one more way of doing it using a method vars(). This method maps attribute
names and their values as a dictionary. For example, for the Point class defined earlier, use the
statements –
>>> p = Point(3, 4)
>>> vars(p) #output is {'y': 4, 'x': 3}

For purposes of debugging, you might find it useful to keep this function handy:

def print_attributes(obj): for attr in


vars(obj):
print(attr, getattr(obj, attr))

Here, print_attributes() traverses the dictionary and prints each attribute name and its corresponding
value. The built-in function getattr() takes an object and an attribute name (as a string) and returns
the attribute’s value.

Santosh Reddy P Page 23


Python Application Programming

GENERAL OOP CONCEPTS

At the earlier age of computers, the programming was done using assembly language. Even though,
the assembly language can be used to produce highly efficient programs, it is not easy to learn or to
use effectively. Moreover, debugging assembly code is quite difficult. At the later stage, the
programming languages like BASIC, COBOL and FORTRAN came into existence. But, these
languages are non-structured and consisting of a mass of tangled jumps and conditional branches
that make a program virtually impossible to understand.

To overcome these problems, the structured or procedural programming methodology was


developed. Here, the actual problem is divided into small independent tasks/modules. Then the
programs are written for each of these tasks and they are grouped together to get the final solution
for the given problem. Thus, the solution design technique for this method is known as top-down
approach. C is the one successful language that adopted structured programming style. However,
even with the structured programming methods, once a project/program reaches a certain size, its
complexity exceeds what a programmer can manage.

The new approach – object oriented programming was developed to overcome the problems with
structured approach. In this methodology, the actual data and the operations to be performed on that
are grouped as a single entity called object. The objects necessary to get the solution of a problem
are identified initially. The interactions between various objects are then identified to achieve the
solution of original problem. Thus, it is also known as bottom-up approach. Object oriented
concepts inhabits many advantages like re- usability of the code, security etc.

In structured programming approach, the programs are written around what is happening rather than
who is being affected. That is, structured programming focuses more on the process or operation and
not on the data to be processed. This is known as process oriented model and this can be thought of
as code acting on data. For example, a program written in C is defined by its functions, any of which
may operate on any type of data used by the program.

But, the real world problems are not organized into data and functions independent of each other and
are tightly closed. So, it is better to write a program around ‘who is being affected’. This kind of
data-centered programming methodology is known as object oriented programming (OOP) and this
can be thought of as data controlling access to code. Here, the behavior and/or characteristics of the
data/objects are used to determine the function to be written for applying them. Thus, the basic idea
behind OOP language is to combine both data and the function that operates on data into a single
unit. Such a unit is called as an object. A function that operates on data is known as a member
function and it is the only means of accessing an object’s data.

Santosh Reddy P Page 24


Python Application Programming

Elements of OOP: The object oriented programming supports some of the basic concepts as
building blocks. Every OOPs language normally supports and developed around these features. They
are discussed hereunder.

Class: A class is a user defined data type which binds data and functions together into a single
entity.

Class is a building block of any object oriented language. As it is discussed earlier, object oriented
programming treats data and the code acting on that data as a connected component. That is, data
and code are not treated separately as procedure oriented languages do. Thus, OOPs suggests to wrap
up the data and functions together into a single entity. Normally, a class represents the prototype of a
real world entity. Hence, a class, by its own, is not having any physical existence. It can be treated as
a user-defined data type.

Since a class is a prototype or blueprint of a real world entity, it consists of number of properties
(known as data members) and behavior (known as member functions). To illustrate this, consider an
example of a class representing a human being shown in the following Figure –

Human Being
- Hair Color
- Number of legs
- Number of eyes
- Skin Color
- Gender

+ Walking
+ Talking
+ Eating

Class diagram for Human Being

Few of the properties of human can be number of legs, number of eyes, gender, number of hands,
hair color, skin color etc. And the functionality or behavior of a human may be walking, talking,
eating, thinking etc.

Object : An object is an instance of a class.


A class is just a prototype, representing a new data type. To use this new data type, we need to create
a variable of this type. Such a variable is known as an object. Thus, an object is a physical entity,
which consumes memory. In OOPs, the object represents a real world data which defines the
properties and behavior of any real world entity. Every object has its unique existence and it is
different from the other objects of a same class.

Santosh Reddy P Page 25


Python Application Programming

Let us refer to the class of human being discussed in previous section. Assume that there are two
persons: Ramu and Radha. Now, properties of Ramu and Radha may be having different values as
shown in the following Table.

Properties of Objects

Property/Attribute Objects
Ramu Radha
Skin color Wheatish Fair
Hair gray black
Number of legs 2 2
Number of eyes 2 2

Also, the walking and talking style of both of them may be different. Hence there are two different
objects of the same class.

Thus, two or more objects of the same class will differ in the values of their properties and way they
behave. But, they share common set of types of properties and behavior.

Encapsulation: The process of binding data and code together into a single entity is called
encapsulation.

It is the mechanism that binds code and the data it manipulates together and keeps both safe from
misuse and unauthorized manipulation. In any OOP language, the basis of encapsulation is the class.
Class defines the structure and behavior (i.e. data and code) that will be shared by a set of objects.
Each object of a given class contains the structure and behavior defined by the class. So, object is
also referred to as an instance of a class and it is thought just as a variable of user-defined data type.
Thus, class is a logical construct and an object is a physical entity. The data defined by the class are
known as member variables and the functions written to operate on that data are known as member
functions or methods. The member variables and functions can be private or public. If a particular
member is private, then only the other members of that class can access that member. That is, a
private member of the class can’t be accessed from outside the class. But, if any member is public,
then it can be accessed from anywhere in the program. Thus, through encapsulation, an OOP
technique provides high security for user’s data and for the entire system.

Data Abstraction: Hiding the implementation details from the end user.

Many a times, abstraction and encapsulation are used interchangeably. But, actually, they are not
same. In OOPs, the end user of the program need not know how the actual function works, or what is
being done inside a function to make it work. The user must know only the abstract meaning of the
task, and he can freely call a function to do that task. The internal details of function may not be
known to the user. Designing the program in such a way is called as abstraction.

Santosh Reddy P Page 26


Python Application Programming

To understand the concept of abstraction, consider a scenario: When you are using Microsoft Word,
if you click on Save icon, a dialogue box appears which allows you to save the document in a
physical location of your choice. Similarly, when you click Open icon, another dialogue box appears
to select a file to be opened from the hard disk. You, as a user will not be knowing how the internal
code would have written so as to open a dialogue box when an icon is being clicked. As a user, those
details are not necessary for you. Thus, such implementation details are hidden from the end user.
This is an abstraction.

Being an OOPs programmer, one should design a class (with data members and member functions)
such a way that, the internal code details are hidden from the end user. OOPs provide a facility of
having member functions to achieve this technique and the external world (normally, a main()
function) needs to call the member function using an object to achieve a particular task.

Inheritance: Making use of existing code.


It is a process by which one object can acquire the properties of another object. It supports the
concept of hierarchical (top-down) classification. For example, consider a large set of animals
having their own behaviors. In that, mammals are of one kind having all the properties of animals
with some additional behaviors that are unique to them. Again, we can divide mammals class into
various mammals like dogs, cats, human etc. Again among the dogs, differentiation is there like
Doberman, German-shepherd, Labrador etc. Thus, if we consider a German-shepherd, it is having all
the qualities of a dog along with its own special features. Moreover, it exhibits all the properties of a
mammal, and in turn of an animal. Hence it is inheriting the properties of animals, then of mammals
and then of dogs along with its own specialties. We can depict it as shown in the Figure given below.

Animal

Reptile Mammal

Human Cat Dog

German-
Doberman Shepherd

Example of Inheritance

Normally, inheritance of this type is also known as “is-a” relationship. Because, we can easily say
“Doberman is a dog”, “Dog is a mammal” etc. Hence, inheritance is termed as Generalization to
Specialization if we consider from top-to-bottom level. On the other hands, it can be treated as
Specialization to Generalization if it is bottom-to-top level.

Santosh Reddy P Page 27


Python Application Programming

This indicates, in inheritance, the topmost base class will be more generalized with only properties
which are common to all of its derived classes (various levels) and the bottom- most class is most
specialized version of the class which is ready to use in a real-world.

If we apply this concept for programming, it can be easily understood that a code written is reusable.
Thus, in this mechanism, it is possible for one object to be a specific instance of a more general
case. Using inheritance, an object need only define those qualities that make it unique object within
its class. It can inherit its general attributes from its parent.

Polymorphism: This can be thought of as one interface, multiple methods.


It is a feature that allows one interface to be used for a general class of actions. The specific action is
determined by the exact nature of the situation. Using this mechanism, function overloading and
operator overloading can be done.

Consider an example of performing stack operation on three different types of data viz. integer,
floating-point and characters. In a non-object oriented programming, we have to write functions with
different name for push and pop operations for all these types of data even though the logic is same
for all the data types. But in OOP languages, we can use the same function names with the data
types of the parameters being different. This is an example for function overloading.

We know that the ‘+’ operator is used for adding two numbers. Conceptually, the concatenation of
two strings is also an addition. But, in non-object oriented programming language, we cannot use ‘+’
operator to concatenate two strings. This is possible in object oriented programming language by
overloading the ‘+’ operator for string operands.

Polymorphism is also meant for economy of expression. That is, the way you express things is more
economical when you use polymorphism. For example, if you have a function to add two matrices,
you can use just a + symbol as:
m3 = m1 + m2;
here, m1, m2 and m3 are objects of matrix class and + is an overloaded operator. In the same
program, if you have a function to concatenate two strings, you can write an overloaded function for
+ operator to do so –
s3= s1+ s2; where s1, s2 and s3 are strings.

Moreover, for adding two numbers, the same + operator is used with its default behavior. Thus, one
single operator + is being used for multiple purposes without disturbing its abstract meaning –
addition. But, type of data it is adding is different. Hence, the way you have expressed your
statements is more economical rather than having multiple functions like –
addMat(m1, m2);
concat(s1, s2); etc.

Santosh Reddy P Page 28

You might also like