Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 17

UNIT-5: Object Oriented Programming OOP in Python- Classes, ‘self variable’, Methods,

Constructor Method, Inheritance, Overriding Methods, and Data hiding.


Error and Exceptions- Difference between an error and Exception, Handling Exception,
try except block, Raising Exceptions, User Defined Exceptions.

Object Oriented Programming OOP in Python:

Python is an object-oriented programming language. You can easily create and use classes
and objects in Python.

Major principles of object-oriented programming system are given below:

o Object
o Class
o Method
o Inheritance
o Polymorphism
o Data Abstraction
o Encapsulation

Object:

Object is an entity that has state and behaviour. It may be physical and logical. For example:
mouse, keyboard, chair, table, pen etc.

Everything in Python is an object, and almost everything has attributes and methods. All
functions have a built-in attribute __doc__, which returns the doc string defined in the
function source code.

Class:

Class can be defined as a collection of objects. It is a logical entity that has some specific
attributes and methods. For example: if you have an employee class then it should contain an
attribute and method i.e. an email id, name, age, salary etc.

Syntax:

class ClassName: 
<statement-1>  
    .  
    .  
    .  
    <statement-N> 
Method:

Method is a function that is associated with an object. In Python, method is not unique to
class instances. Any object type can have methods.

Inheritance:

Inheritance is a feature of object-oriented programming. It specifies that one object acquires


all the properties and behaviours of parent object. By using inheritance you can define a new
class with a little or no changes to the existing class. The new class is known as derived class
or child class and from which it inherits the properties is called base class or parent class. It
provides re-usability of the code.

Polymorphism:

Polymorphism is made by two words "poly" and "morphs". Poly means many and Morphs
means form, shape. It defines that one task can be performed in different ways. For example:
You have a class animal and all animals talk. But they talk differently. Here, the "talk"
behaviour is polymorphic in the sense and totally depends on the animal. So, the abstract
"animal" concept does not actually "talk", but specific animals (like dogs and cats) have a
concrete implementation of the action "talk".

Encapsulation:

Encapsulation is also the feature of object-oriented programming. It is used to restrict access


to methods and variables. In encapsulation, code and data are wrapped together within a
single unit from being modified by accident.

Data Abstraction:

Data abstraction and encapsulation both are often used as synonyms. Both are nearly
synonym because data abstraction is achieved through encapsulation. Abstraction is used to
hide internal details and show only functionalities. Abstracting something means to give
names to things, so that the name captures the core of what a function or a whole program
does.

Classes and Self variable:

Classes are a way of grouping together related data and functions which act upon that data. In
fact a class is the basic building block in Python.A class is a kind of data type, just like a
string, integer or list. When we create an object of that data type, we call it an instance of a
class. The data values which we store inside an object are called attributes, and the functions
which are associated with the object are called methods. We have already used the methods
of some built-in objects, like strings and lists. When we design our own objects, we have to
decide how we are going to group things together, and what our objects are going to
represent.
Creating Classes:
The class statement creates a new class definition. The name of the class immediately
follows the keyword class followed by a colon as follows –

Syntax:

class ClassName:
'Optional class documentation string'
class_suite

 The class has a documentation string, which can be accessed


via ClassName.__doc__.
 The class_suite consists of all the component statements defining class members,
data attributes and functions.

Example:

class Employee:
‘Common base class for all employees’
empCount = 0

def __init__(self, name, salary):


self.name = name
self.salary = salary
Employee.empCount += 1

def displayCount(self):
print “Total Employee %d” % Employee.empCount

def displayEmployee(self):
print “Name : “, self.name, “, Salary: “, self.salary

The variable empCount is a class variable whose value is shared among all instances of a this
class. This can be accessed as Employee.empCount from inside the class or outside the class.
The first method __init__() is a special method, which is called class constructor or
initialization method. You declare other class methods like normal functions with the
exception that the first argument to each method is self.  This self-reference is what we use to
set and get the instance’s attributes and to access its other methods, from within a method.

Creating Instance Objects:


Once a class is defined, the next job is to create an object(or instance) of that class.

Syntax:

object_name = class_name( )

To create instances of a class, you call the class using class name and pass in whatever
arguments its __init__ method accepts.

"This would create first object of Employee class"


emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
emp2 = Employee("Manni", 5000)

Accessing Attributes:
The object can then access class variables and class methods using the dot operator (.) .
Class variable would be accessed using class name as follows −

emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

Now, putting all the concepts together −

class Employee:
'Common base class for all employees'
empCount = 0

def __init__(self, name, salary):


self.name = name
self.salary = salary
Employee.empCount += 1

def displayCount(self):
print "Total Employee %d" % Employee.empCount

def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary

"This would create first object of Employee class"


emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
emp2 = Employee("John", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

Output:

Name : Zara ,Salary: 2000


Name : John ,Salary: 5000
Total Employee 2

You can add, remove, or modify attributes of classes and objects at any time −

emp1.age = 7 # Add an 'age' attribute.


emp1.age = 8 # Modify 'age' attribute.
del emp1.age # Delete 'age' attribute.

Built-In Class Attributes:


Every Python class keeps following built-in attributes and they can be accessed using dot
operator like any other attribute −

 __dict__: Dictionary containing the class's namespace.

 __doc__: Class documentation string or none, if undefined.

 __name__: Class name.

 __module__: Module name in which the class is defined. This attribute is


"__main__" in interactive mode.
 __bases__: A possibly empty tuple containing the base classes, in the order of their
occurrence in the base class list.

Methods:

A method is a piece of code that is called by name that is associated with an object. In most
respects it is identical to a function except for two key differences. We have already seen
some methods, such as keys and values, which were invoked on dictionaries. Each method is
associated with a class and is intended to be invoked on instances of that class.

Methods are just like functions, with two 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.

Example:
class Dog:
def my_method(self):
print "I am a Dog"

dog = Dog()
dog.my_method() # Prints "I am a Dog"

Constructor Method:

A constructor is a special type of method (function) that is called when it instantiates an


object using the definition found in your class. The constructors are normally used to
initialize (assign values) to the instance variables. Constructors also verify that there are
enough resources for the object to perform any start-up task.

Creating a constructor:

A constructor is a class function that begins with double underscore ( _ ). The name of the
constructor is always the same __init__( ).The __init__( ) method is automatically executed
when an object of a class is created.

While creating an object, a constructor can accept arguments if necessary. When you create a
class without a constructor, Python automatically creates a default constructor that doesn't do
anything.

Every class must have a constructor, even if it simply relies on the default constructor.
Example:

Inheritance:
The technique of creating a new class from an existing class is called Inheritance. The old or
existing class is called base class and the new class is known as derived class or sub class.

The child class inherits the attributes of its parent class, and you can use those attributes as if
they were defined in the child class. A child class can also override data members and
methods from the parent.

Syntax:
Class DerivedClass(BaseClass):
body_of_derived_class

Derived classes are declared much like their parent class; however, a list of base classes to
inherit from is given after the class name –

class SubClassName (ParentClass1[, ParentClass2, ...]):


'Optional class documentation string'
class_suite

Example:

Class Person:
def__init__(self, name, age):
self.name = name
self.age = age
def display(self):
print(“NAME:”, self.name)
print(“AGE:”,self.age)
class Teacher(Person):
def __init__(self, name, age, exp, r_area):
Person.__init__(self, name, age)
self.exp = exp
self.r_area = r_area
def displayData(self):
Person.display(self)
print(“EXPERIENCE:”, self.exp)
print(“RESEARCH AREA:”, self.r_area)
Class Student(Person):
def __init__(self, name, age, course, marks):
Person.__init__(self, name, age)
self.course = course
self.marks = marks
def displayData(self):
Person.display(self)
print(“COURSE:”, self.course)
print(“MARKS:”, self.marks)
print(“*********TEACHER*********)
T = Teacher(“Jaya”, 43, 20, “Recommender Systems”)
T. displayData( )
print(“*********STUDENT*********”)
S = Student(“Latha”, 20,”B.Tech”, 78)
S.displayData( )

Output:

*********TEACHER********
NAME : Jaya
AGE : 43
EXPERIENCE : 20
RESEARCH AREA : Recommender Systems
*********STUDENT********
NAME : Latha
AGE : 20
COURSE : BTech
MARKS : 78

Similar way, you can drive a class from multiple parent classes as follows −

class A: # define your class A


.....

class B: # define your class B


.....

class C(A, B): # subclass of A and B


.....

You can use issubclass() or isinstance() functions to check a relationships of two classes and
instances.

 The issubclass(sub, sup) boolean function returns true if the given subclass sub is


indeed a subclass of the superclass sup.
 The isinstance(obj, Class) boolean function returns true if obj is an instance of
class Class or is an instance of a subclass of Class

Types of Inheritance:

1. Multiple Inheritance: When a derived class inherits features from more that one base
class it is called Multiple Inheritance.
2. Multi-level Inheritance: The technique of deriving a class from an already derived
class is called Multi-level Inheritance.
3. Multi-path Inheritance: Deriving a class from other derived classes that are in turn
derived from the same base class is called Multi-path Inheritance.

Overriding Methods
Override means having two methods with the same name but doing different tasks. It means
that one of the methods overrides the other. Through method overriding a class may “copy”
another class, avoiding duplicated code, and at the same time enhance or customize part of
it.

You can always override your parent class methods. One reason for overriding parent's
methods is because you may want special or different functionality in your subclass.

Example:
class Parent: # define parent class
def myMethod(self):
print 'Calling parent method'

class Child(Parent): # define child class


def myMethod(self):
print 'Calling child method'

c = Child( ) # instance of child


c.myMethod( ) # child calls overridden method

Output:

Calling child method

Base Overloading Methods:


Following table lists some generic functionality that you can override in your own classes −

S.No Method, Description & Sample Call

1 __init__ ( self [,args...] )


Constructor (with any optional arguments)
Sample Call : obj = className(args)

2 __del__( self )
Destructor, deletes an object
Sample Call : del obj
3 __repr__( self )
Evaluatable string representation
Sample Call : repr(obj)

4 __str__( self )
Printable string representation
Sample Call : str(obj)

5 __cmp__ ( self, x )
Object comparison
Sample Call : cmp(obj, x)

Data hiding:
An object's attributes may or may not be visible outside the class definition. You need to
name attributes with a double underscore prefix, and those attributes then are not be directly
visible to outsiders.

Example:
#!/usr/bin/python

class JustCounter:
__secretCount = 0

def count(self):
self.__secretCount += 1
print self.__secretCount

counter = JustCounter()
counter.count()
counter.count()
print counter.__secretCount
Output:

1
2
Traceback (most recent call last):
File "test.py", line 12, in <module>
print counter.__secretCount
AttributeError: JustCounter instance has no attribute '__secretCount'

Python protects those members by internally changing the name to include the class name.
You can access such attributes as object._className__attrName. If you would replace your
last line as following, then it works for you −

.........................
print counter._JustCounter__secretCount

Output 2:

1
2
2

Error and Exceptions:

In our programs, we had been getting some or the other errors but we had not mentioned
much about them. Basically, there are two types of errors.

Abnormal or unexpected
behaviour of program

Error Exception

Logical error Syntactic error Synchronous Asynchronous


Difference between an error and Exception:

Exceptions are those which can be handled at the run time whereas errors cannot be handled.
An Exception is an Object of a type deriving from the System.Exception class. System
Exception is thrown by the CLR (Common Language Runtime) when errors occur that are
nonfatal and recoverable by user programs. It is meant to give you an opportunity to do
something with throw statement to transfer control to a catch clause in a try block.

Example:

>>>5/0
Traceback (most recent call last):
File “pyshell#5>”, line 1, in <module>
5/0
ZeroDivisionError: integer division or module by zero
>>>’Roll No’ + 123
Traceback (most recent call last):
File “pyshell#8>”, line 1, in <module>
’Roll No’ + 123
TypeError: cannot concatenate ‘str’ and ‘int’ objects

An Error is something that most of the time you cannot handle it. Errors are unchecked
exception and the developer is not required to do anything with these. Errors normally tend to
signal the end of your program, it typically cannot be recovered from and should cause you
exit from current program. It should not be caught or handled.

All the Errors are Exceptions but the reverse is not true. In general Errors are which nobody
can control or guess when it happened, on the other hand Exception can be guessed and can
be handled.

Example:

>>> while True print('Hello world')


File "<stdin>", line 1
while True print('Hello world')
^
SyntaxError: invalid syntax

Handling Exception and try except block:


Exception can be said to be any abnormal condition in a program resulting to the disruption in the
flow of the program. Whenever an exception occurs the program halts the execution and thus further
code is not executed. Thus exception is that error which python script is unable to tackle with.

Python has many built-in exceptions which forces your program to output an error when
something in it goes wrong. When these exceptions occur, it causes the current process to
stop and passes it to the calling process until it is handled.

For example, if function A calls function B which in turn calls function C and an exception occurs in


function C. If it is not handled in C, the exception passes to B and then to A.

Hierarchy Of Exception:

1. ZeroDivisionError: Occurs when a number is divided by zero.


2. NameError: It occurs when a name is not found. It may be local or global.
3. IndentationError: If incorrect indentation is given.
4. IOError: It occurs when Input Output operation fails.
5. EOFError: It occurs when end of file is reached and yet operations are being
performed

Catching Exceptions in Python

In Python, exceptions can be handled using a try block and except block. A critical operation
which can raise exception is placed inside the try clause and the code that handles exception
is written in except clause.

Syntax:

try:
statements
except ExceptionName:
statements

Detailed Syntax:

try:  

malicious code  

except Exception1:  

 execute code  

except Exception2:  

execute code  
. . . .  

. . . .  

except ExceptionN:  

execute code  

else:  

In case of no exception, execute the else block code.  

Example:

try:  

    a=10/0  

    print a  

except ArithmeticError:  

        print "This statement is raising an exception"  

else:  

    print "Welcome"  

Output:

>>>   

This statement is raising an exception  

>>>  

Explanation:

The malicious code (code having exception) is enclosed in the try block.

Try block is followed by except statement. There can be multiple except statement
with a single try block.

Except statement specifies the exception which occurred. In case that exception is
occurred, the corresponding statement will be executed.

At the last you can provide else statement. It is executed when no exception is
occurred.

Raising Exceptions:
You can explicitly throw an exception in Python using raise statement. raise will cause an
exception to occur and thus execution control will stop in case it is not handled.

Syntax:

1. raise Exception_class,<value>  

Example:

1. try:  

2.     a=10  

3.     print a  

4.     raise NameError("Hello")  

5. except NameError as e:  

6.         print "An exception occurred"  

7.         print e  

Output:

1. >>>   

2. 10  

3. An exception occurred  

4. Hello  

5. >>>  

Explanation:

i) To raise an exception, raise statement is used. It is followed by exception class name.

ii) Exception can be provided with a value that can be given in the parenthesis. (here, Hello)

iii) To access the value "as" keyword is used. "e" is used as a reference variable which stores
the value of the exception.

User Defined Exceptions (Custom Exception):


Exception

Built-in User-defined

Creating your own Exception class or User Defined Exceptions by deriving classes from the
standard built-in exceptions are known as Custom Exception.

Example:

1. class ErrorInCode(Exception):  

2.      def __init__(self, data):  

3.    self.data = data  

4.      def __str__(self):  

5.         return repr(self.data)  

6.   

7. try:  

8.     raise ErrorInCode(2000)  

9. except ErrorInCode as ae:  

10.     print "Received error:", ae.data  

Output:

1. >>>   

2. Received error : 2000  

3. >>>  

You might also like