0% found this document useful (0 votes)
96 views

Object Oriented Programming With Python

The document discusses object-oriented programming concepts in Python including classes, objects, attributes, methods, inheritance, polymorphism, and encapsulation. It provides examples of defining a Rectangle class with attributes like width and height, and methods like getArea. The class is used to create Rectangle objects that store their own attribute values and allow calling methods on each object independently.

Uploaded by

ADSHOD PEC
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
96 views

Object Oriented Programming With Python

The document discusses object-oriented programming concepts in Python including classes, objects, attributes, methods, inheritance, polymorphism, and encapsulation. It provides examples of defining a Rectangle class with attributes like width and height, and methods like getArea. The class is used to create Rectangle objects that store their own attribute values and allow calling methods on each object independently.

Uploaded by

ADSHOD PEC
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 36

UNITI

OBJECT ORIENTED PROGRAMMING WITH PYTHON 9


Classes and OOP: classes, objects, attributes and methods; defining classes; design with classes, data
modeling; persistent storage of objects - OOP, continued: inheritance, polymorphism, operator overloading;
abstract classes; exception handling, try block. Illustrative programs: demonstrate the concept of class and
objects.

OBJECT-ORIENTEDPROGRAMMING
Object-OrientedProgramming(OOP) is a programming language model organizedaround
objects ratherthanactionsanddata.Anobject-orientedprogramcanbecharacterizedasdatacontrollingaccess to
code.Concepts of OOPS
Object
Class
Inheritance
Polymorphism
Abstraction
Encapsulation
OBJECT
Object means a real word entity such as pen, chair, table etc. Any entity that has state and behavior
isknown as an object. Object can be defined as an instance of a class. An object contains an address and
takesup some space in memory. Objects can communicate without knowing details of each other's data or
code,the onlynecessarythingis that thetypeofmessageacceptedand typeof response returned bythe objects.
Anobjecthasthreecharacteristics:
 state:representsdata(value)ofanobject.
 behavior:representsthe behavior(functionality)ofanobjectsuch asdeposit,withdrawetc.
 identity: Object identity is typically implemented via a unique ID. The value of the ID is
notvisibleto the externaluser. But, itis used internallybythe JVM toidentifyeach object uniquely.
CLASS
Collection of objects is called class. It is a logical entity. A class can also be defined as a
blueprintfrom which you can create an individual object. A class consists of Data members and methods.
The primarypurposeofaclassistoholddata/information.The memberfunctions determinethebehavioroftheclass,
i.e. provide a definition for supporting various operations on data held in the form of an object.Class
doesn’tstoreanyspace.

Class Definition Syntax


The simplest form of class definition looks like this:

class ClassName:
   'Brief description of the class (Optional)'
   # Code ...
1
 To define a class, we use the class keyword, followed by the name of the class and the colon (:). The first
line in the class body is a string that briefly describes this class. (Optional), we can access this string
via ClassName.__doc__
 In the class body, you can declare  attributes, methods, and constructors.

Attribute:

The attribute is a member of the class. For example, the rectangle has two attributes including width and
height.

Method:
 The method of class is similar to a normal function but it is a function of class, in order to use it, we need
to call through object.
 The first parameter of the method is always self (a keyword that refers to the class itself).

Constructor:
 Constructor is a special method of class, which is always named __init__.
 The first parameter of the constructor is always self (a keyword refers to the class itself).
 Constructor is used to create an object.
 Constructor assigns values of the parameter to the properties of the object that will be created.
 We can only define a constructor in class.
 If the class is not defined by the constructor, Python assumes that it inherit constructor of parent class.

#rectangle.py
# Rectangle.
class Rectangle :
    'This is Rectangle class'
    
    # Method to create object (Constructor)
    def __init__(self, width, height):
         
        self.width= width
        self.height = height
    
     def getWidth(self):       
        return self.width
     
     
    def getHeight(self):       
        return self.height

2
 
    # Method to calculate Area.
    def getArea(self):
         
        return self.width * self.height

Create an object from the Rectangle class:

#testRectangle.py

from rectangle import Rectangle


 
# Create 2 objects: r1 & r2
r1 = Rectangle(10,5)
 
r2 = Rectangle(20,11)
 
print ("r1.width = ", r1.width)
print ("r1.height = ", r1.height)
print ("r1.getWidth() = ", r1.getWidth())
print ("r1.getArea() = ", r1.getArea())
 
print ("-----------------")
 
print ("r2.width = ", r2.width)
print ("r2.height = ", r2.height)
print ("r2.getWidth() = ", r2.getWidth())
print ("r2.getArea() = ", r2.getArea())

Output

3
What happens when you create an object from a class?

When you create an object of the Rectangle class, the constructor of that class will be called to create an object,
and the attributes of the object will be assigned the value from the parameter. It is similar to the illustration
below:

Constructor with default parameters


Unlike other languages, the class in Python only has one constructor. However, Python allows the parameter to
have a default value.

#person.py
class Person :
   
    # The age and gender parameters has a default value.
    def __init__ (self, name, age = 1, gender = "Male" ):
         
        self.name = name
        self.age = age
        self.gender= gender
4
         
     
    def showInfo(self):
         
        print ("Name: ", self.name)
        print ("Age: ", self.age)
        print ("Gender: ", self.gender)

#testPerson.py
from person import Person
 
# Create an object of Person.
aimee = Person("Aimee", 21, "Female")
 
 
aimee.showInfo()
 
print (" --------------- ")
 
# default age, gender.
alice = Person( "Alice" )
 
alice.showInfo()
 
print (" --------------- ")
 
# Default gender.
tran = Person("Tran", 37)

tran.showInfo()
 

Output

5
ATTRIBUTES
In Python, there are 2 similar concepts that we need to distinguish them:
1. Attribute
2. Class's variable

To simplify that, let's analyze the example below:

Objects created from one class will be located at different addresses on memory, and their "same name"
attributes also have different addresses on memory. For example:

#testAttributePlayer.py
from player import Player
 
 
player1 = Player("Tom", 20)
 
player2 = Player("Jerry", 20)
 
6
print ("player1.name = ", player1.name)
print ("player1.age = ", player1.age)
 
 
print ("player2.name = ", player2.name)
print ("player2.age = ", player2.age)
 
print (" ------------ ")
 
print ("Assign new value to player1.age = 21 ")
 
# Assgin new value to age attribute of player1.
player1.age = 21
 
print ("player1.name = ", player1.name)
print ("player1.age = ", player1.age)
 
print ("player2.name = ", player2.name)
print ("player2.age = ", player2.age)

Output

Python allows you to create a new attribute for a pre-existing object. For example,  the player1 object and the
new attribute named as address.

7
#testNewAttributePlayer.py

from player import Player


 
 
player1 = Player("Tom", 20)
 
player2 = Player("Jerry", 20)
 
# Create a new attribute named 'address' for player1.
player1.address = "USA"
 
print ("player1.name = ", player1.name)
print ("player1.age = ", player1.age)
print ("player1.address = ", player1.address)
 
print (" ------------------- ")
 
print ("player2.name = ", player2.name)
print ("player2.age = ", player2.age)
 
# player2 has no attribute 'address' (Error!!)
print ("player2.address = ", player2.address)

Output:

8
Function Attributes

Normally, you access to the attribute of an object through the "dot" operator (e.g player1.name).
However Python allows you to access to it via function.

Function Description
Returns the value of the attribute, or returns the default value if the
getattr(obj, name[, default])
object does not have this attribute.
Check whether this object has an attribute given by the parameter
hasattr(obj,name)
'name' or not.
setattr(obj,name,value) Set value to attribute. If the attribute does not exist, it will be created.
delattr(obj, name) Delete attribute.

#testAttFunctions.py
from player import Player
 
player1 = Player("Tom", 20)
 
# getattr(obj, name[, default])
print ("getattr(player1,'name') = " ,getattr(player1,"name") )
 
 
print ("setattr(player1,'age', 21): ")
 
# setattr(obj,name,value)
setattr(player1,"age", 21)
 
 
print ("player1.age = ", player1.age)

9
 
# Check player1 has 'address' attribute?
hasAddress=  hasattr(player1, "address")
 
print ("hasattr(player1, 'address') ? ", hasAddress)
 
# Create attribute 'address' for object 'player1'
print ("Create attribute 'address' for object 'player1'")
setattr(player1, 'address', "USA")
 
print ("player1.address = ", player1.address)
 
# Delete attribute 'address'.
Delattr(player1, “address”)

Output:

Built-In Class Attributes

Python classes are descendants of the object class. So they inherit the following attributes:


Attribute Description
__dict__ Giving information about this class in a short, easy to understand, as one dictionary
__doc__ Returns a string describing the class, or returns None if it is not defined
Returns an object, containing information about the class, which has many useful attributes,
__class__
including the __name__ attribute.
Returns the 'module' name of the class, or returns "__main__" if that class is defined in the
__module__
module being run.

#testBuildInAttributes.py

class Customer :
    'This is Customer class'
    
    def __init__(self, name, phone, address):
1
0
        
        self.name = name
        self.phone = phone
        self.address = address
 
 
john = Customer("John",1234567, "USA")
  
 
print ("john.__dict__ = ", john.__dict__)
 
print ("john.__doc__ = ", john.__doc__)
 
 
print ("john.__class__ = ", john.__class__)
 
print ("john.__class__.__name__ = ", john.__class__.__name__)
print ("john.__module__ = ", john.__module__)
 

Output:

Class's Variables
In Python, Class's Variable concept is equivalent to static Field concept of other languages such
as Java, CSharp. Variables of the class can be accessed via the class name or the object.

1
1
Each of the Class's Variable has an address on memory. And it is shared with all the objects of class.

#testVariablePlayer.py

from player import Player


 
player1 = Player("Tom", 20)
 
 
player2 = Player("Jerry", 20)
 
# Access via class name.
print ("Player.minAge = ", Player.minAge)
 
# Access via object.
print ("player1.minAge = ", player1.minAge)
print ("player2.minAge = ", player2.minAge)
 
 
print (" ------------ ")
 
 
print ("Assign new value to minAge via class name, and print..")
 
1
2
# Assgin new value to minAge via class name
Player.minAge = 19
 
 
print ("Player.minAge = ", Player.minAge)
print ("player1.minAge = ", player1.minAge)
print ("player2.minAge = ", player2.minAge)

Output:

DATA MODELING

Objects are Python’s abstraction for data. All data in a Python program is represented by objects or by relations
between objects. (In a sense, and in conformance to Von Neumann’s model of a “stored program computer”,
code is also represented by objects.)

In Python, everything is an object. Each object has an identity, a type and a value.

Example:We can think of identity as an object’s address in memory

>>> player_1 = "Maradona"


>>> id(player_1)
139780790567600
>>> age = 53
>>> id(age)
9753824

Here, the id() gives us the identity that we were talking about, which is a unique integer that never changes
during the lifetime of an object. We can think of identity as an object’s address in memory.

1
3
Example: We can check if two objects are the same with is operator.

>>> player_2 = "Pele"


>>> player_1 is player_2 #They are not referring the same object
False >>>player_copy = player_1

>>> player_1 is player_copy #They are referring the same object


True>>> id(player_2)
139780790567984

>>> id(player_copy)
139780790567600

Example:If we want to check the type of these objects, we can use type().

>>> type(age)
<class ‘int’>
>>> type(player_1)
<class 'str'>

The type of an object cannot change.

Type specifies two things:


– what operations are allowed
– the set of values the object can hold

The value of an object can be changed if the object is mutable and if the object is immutable the value of it
cant be changed.

The value of an object is what the object is holding in it. Here 53 is the valueof age and Maradona is the value
of player_1 . The value of an object can be changed if the object is mutable and if the object is immutable the
value of it can’t be changed.

age = 53 is an integer type object with value 53 and has the id 9753824

That means the age = 53 is an integer type object with value 53 and has the id 9753824 and if we now change

the age to 54 , it will be referring to a different object

>>> age = 54 # here, age is referring to a different object


>>> id(age) # showing different identity than the previous one
9753856

So, if we want to change the value of player_1 then both objects player_copy and player_1 will not show the
same identity.
1
4
>>> player_1 = "Messi" # assigning new value to
>>>player_copy
'Maradona'
>>> player_1 is player_copy
False

So, both player_1 aka string and age aka integers are immutable types. There are other immutable types. such as


— integers, floats, strings, tuples. On the other hand, mutable types are lists, dictionaries, and sets. Now, looking
into the mutable types.

>>> players = ["Messi", "Maradona", "Pele"]


>>>players_copy = players # Coping the reference to the list
object,not the list object itself.>>> players is players_copy
True>>> players[0]="Ronaldo" # Changing the first element
>>> players
['Ronaldo', 'Maradona', 'Pele']
>>>players_copy
['Ronaldo', 'Maradona', 'Pele'] # They refer to same list object.>>>players.append("Pirlo") # Appending a
new element
>>> players
['Ronaldo', 'Maradona', 'Pele', 'Pirlo']
>>>players_copy
['Ronaldo', 'Maradona', 'Pele', 'Pirlo']>>>players_copy.append("Cruyf")
>>>players_copy
['Ronaldo', 'Maradona', 'Pele', 'Pirlo', 'Cruyf']
>>> players
['Ronaldo', 'Maradona', 'Pele', 'Pirlo', 'Cruyf']

As both players and players_copy referring to the same list object, changes in one list will have an effect on the


other variable.

In the above example, we mutated the players list by changing the first value and using append() method.
Asboth players and players_copy referring to the same list object, changes in one list will have an effect on the
other variable.

PERSISTENT STORAGE OF OBJECTS

Persistence denotes a process or an object that continues to exist even after its parent process or object ceases, or
the system that runs it is turned off. When a created process needs persistence, non-volatile storage, including a
hard disk, is used instead of volatile memory like RAM.

For example, imagine that you're using the Chrome browser on the Windows operating system and, due to some
technical issues, the browser process was shut down or killed. The browser restarts the next time you open it and
attempts to reopen any tabs that were open when it crashed. A persistent process thus exists even if it failed or
was killed for some technical reasons. The persistent state is the state that remains even after a process shuts
1
5
down. Persistent process states are stored in persistent storage (non-volatile storage like hard drives) before the
system fails or shuts down. They're easily retrieved once the system is turned on. The core processes of the
operating system must be persistent for maintaining the data, device, or workspace in a similar state when the
system is switched on.

Types of Persistence
There are two types of persistence: object persistence and process persistence. In data terms, object
persistence refers to an object that is not deleted until a need emerges to remove it from the memory. Some
database models provide mechanisms for storing persistent data in the form of objects.
In process persistence, processes are not killed or shut down by other processes and exist until the user kills
them. For example, all of the core processes of a computer system are persistent for enabling the proper
functioning of the system. Persistent processes are stored in non-volatile memory. They do not need special
databases like persistent objects.

Object Persistence in Databases


A persistent database stores persistent data in the form of objects, or records that are durable when changing
devices and software. Persistent data is stable and recoverable. Traditional relational database management
systems (RDBMS) store persistent data in the form of records and tables. However, they cannot store objects and
their relationships. Objects have necessary features (like encapsulation, inheritance, persistence, and
polymorphism) that do not translate well into records and tables. Thus, certain special databases like object-
oriented database management systems (OODBMS) and object relational database management systems
(ORDBMS) are needed for storing objects and preserving object persistence.

shelve – Persistent storage of arbitrary Python objects

Purpose:The shelve module implements persistent storage for arbitrary Python objects which can be
pickled,using a dictionary-like API.

The shelve module can be used as a simple persistent storage option for Python objects when a relational database
is overkill. The shelf is accessed by keys, just as with a dictionary. The values are pickled and written to a database
created and managed by anydbm.

Creating a new Shelf


The simplest way to use shelve is via the DbfilenameShelf class. It uses anydbm to store the data. You can use the
class directly, or simply call shelve.open():

importshelve

s=shelve.open('test_shelf.db')
try:
s['key1']={'int':10,'float':9.5,'string':'Sample data'}
finally:
s.close()

1
6
To access the data again, open the shelf and use it like a dictionary:

importshelve

s=shelve.open('test_shelf.db')
try:
existing=s['key1']
finally:
s.close()

printexisting

If we run both sample scripts, we should see:

$ python shelve_create.py
$ python shelve_existing.py

{'int': 10, 'float': 9.5, 'string': 'Sample data'}

The dbm module does not support multiple applications writing to the same database at the same time. If you
know your client will not be modifying the shelf, you can tell shelve to open the database read-only.

importshelve

s=shelve.open('test_shelf.db',flag='r')
try:
existing=s['key1']
finally:
s.close()

printexisting

If the program tries to modify the database while it is opened read-only, an access error exception is generated. The
exception type depends on the database module selected by anydbm when the database was created.

Write-back
Shelves do not track modifications to volatile objects, by default. That means if we change the contents of an item
stored in the shelf, we must update the shelf explicitly by storing the item again.

importshelve

s=shelve.open('test_shelf.db')
try:
prints['key1']

1
7
s['key1']['new_value']='this was not here before'
finally:
s.close()

s=shelve.open('test_shelf.db',writeback=True)
try:
prints['key1']
finally:
s.close()

In this example, the dictionary at ‘key1’ is not stored again, so when the shelf is re-opened, the changes have not
been preserved.

$ python shelve_create.py
$ python shelve_withoutwriteback.py

{'int': 10, 'float': 9.5, 'string': 'Sample data'}


{'int': 10, 'float': 9.5, 'string': 'Sample data'}

To automatically catch changes to volatile objects stored in the shelf, open the shelf with writeback enabled. The
writeback flag causes the shelf to remember all of the objects retrieved from the database using an in-memory
cache. Each cache object is also written back to the database when the shelf is closed.

importshelve

s=shelve.open('test_shelf.db',writeback=True)
try:
prints['key1']
s['key1']['new_value']='this was not here before'
prints['key1']
finally:
s.close()

s=shelve.open('test_shelf.db',writeback=True)
try:
prints['key1']
finally:
s.close()

Although it reduces the chance of programmer error, and can make object persistence more transparent, using
writeback mode may not be desirable in every situation. The cache consumes extra memory while the shelf is open,
and pausing to write every cached object back to the database when it is closed can take extra time. Since there is
no way to tell if the cached objects have been modified, they are all written back. If your application reads data
more than it writes, writeback will add more overhead than you might want.

$ python shelve_create.py
$ python shelve_writeback.py

1
8
{'int': 10, 'float': 9.5, 'string': 'Sample data'}
{'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'}
{'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'}

INHERITANCE

Inheritance allows us to define a class that inherits all the methods and properties from another class.

Parent class is the class being inherited from, also called base class.

Child class is the class that inherits from another class, also called derived class.

Create a Parent Class

Any class can be a parent class, so the syntax is the same as creating any other class:

Example

Create a class named Person, with firstname and lastname properties, and a printname method:

class Person:
  def __init__(self, fname, lname):

1
9
    self.firstname = fname
    self.lastname = lname

  def printname(self):
    print(self.firstname, self.lastname)

#Use the Person class to create an object, and then execute the printname method:

x = Person("John", "Doe")
x.printname()

Create a Child Class

To create a class that inherits the functionality from another class, send the parent class as a parameter when
creating the child class:

Example

Create a class named Student, which will inherit the properties and methods from the Person class:

class Student(Person):
  pass

Note: Use the pass keyword when we do not want to add any other properties or methods to the class.

Now the Student class has the same properties and methods as the Person class.

Example

Use the Student class to create an object, and then execute the printname method:

x = Student("Mike", "Olsen")
x.printname()

Add the __init__() Function

So far we have created a child class that inherits the properties and methods from its parent.

We want to add the __init__() function to the child class (instead of the pass keyword).

Example

Add the __init__() function to the Student class:

2
0
class Student(Person):
  def __init__(self, fname, lname):
    #add properties etc.

When you add the __init__() function, the child class will no longer inherit the parent's __init__() function.

To keep the inheritance of the parent's __init__() function, add a call to the parent's __init__() function:

class Student(Person):
  def __init__(self, fname, lname):
    Person.__init__(self, fname, lname)

Now we have successfully added the __init__() function, and kept the inheritance of the parent class, and we are
ready to add functionality in the __init__() function.

Use the super() Function

Python also has a super() function that will make the child class inherit all the methods and properties from its
parent:

class Student(Person):
  def __init__(self, fname, lname):
    super().__init__(fname, lname)

By using the super() function, you do not have to use the name of the parent element, it will automatically inherit
the methods and properties from its parent.

Add Properties

Add a property called graduationyear to the Student class:

class Student(Person):
  def __init__(self, fname, lname):
    super().__init__(fname, lname)
    self.graduationyear = 2019

In the example below, the year 2019 should be a variable, and passed into the Student class when creating
student objects. To do so, add another parameter in the __init__() function:

Add a year parameter, and pass the correct year when creating objects:

class Student(Person):
2
1
  def __init__(self, fname, lname, year):
    super().__init__(fname, lname)
    self.graduationyear = year

x = Student("Mike", "Olsen", 2019)

Add Methods
Add a method called welcome to the Student class:

class Student(Person):
  def __init__(self, fname, lname, year):
    super().__init__(fname, lname)
    self.graduationyear = year

  def welcome(self):
    print("Welcome", self.firstname, self.lastname, "to the class of",
self.graduationyear)

x = Student("Mike", "Olsen", 2019)


x.welcome()
If you add a method in the child class with the same name as a function in the parent class, the
inheritance of the parent method will be overridden

POLYMORPHISM
When onetaskisperformedbydifferentways
i.e.knownaspolymorphism.Forexample:toconvincethecustomer differently, to drawsomethinge.g.
shapeorrectangleetc.

Polymorphismisclassified intotwo ways:


MethodOverloading(CompiletimePolymorphism)
Method Overloading is a feature that allows a class to have two or more methods having the same name
butthe arguments passed to the methods are different. Compile time polymorphism refers to a process in
whichacall to an overloaded methodis resolved at compiletimeratherthan atruntime.
MethodOverriding(RuntimePolymorphism)
Ifsubclass(childclass)hasthe same methodasdeclaredinthe parentclass,itisknown as methodoverriding in
java.In other words, If subclass provides the specific implementation of the method that hasbeenprovided
byoneofits parent class, it isknown asmethod overriding.

A simple example of polymorphism in python


2
2
 In the example given below we can clearly see that the addition operator is used in different way.   
>>>4+5
9
In this example as the data sent are two integer values, the operator did the addition operation of two
numbers. 
>>>”4”+”5”
45
In the second example, as the same values are sent as data in the form of string, and the same operator did
the concatenation (concatenation is the process by which two strings are joined end-to-end) of the two
strings.
>>>”ab”+”cd”
abcd 
In the third example, the data sent are two strings but the operator is same as the above and it did the
concatenation of the two strings.

How to use polymorphism?


Overloading
Overloading is divided into two types
 Operator Overloading
 Method Overloading

Operator overloading 
Operator overloading is the type of overloading in which an operator can be used in multiple ways beyond
its predefined meaning.
>>>print(2*7)
14
>>>print(”a”*3)
aaa
So in the above example the multiplication operator did the multiplication of two numbers in the first
one, but in the second one as the multiplication of a string and an integer is not possible so the
character  is printed repeatedly for 3 times. So it shows how we can use a single operator in different
way.

Practical implementation of operator overloading .

Example 1:
class Vehicle:
def __init__(self, fare):
self.fare = fare
2
3
bus= Vehicle(20)
car= Vehicle(30)
total_fare=bus+ car
print(total_fare)

Output:
Traceback (most recent call last):
  File “G:\python pycharm project\main.py”, line 7, in <module>
    total_fare=bus+ car
TypeError: unsupported operand type(s) for +: ‘Vehicle’ and ‘Vehicle’
Here in the above example an error has occurred, this is because python has no idea how to add two objects
together. Here Vehicle is the object. 
Now comes the application of operator overloading here. 
Now we will overload the special function __add__  operator.
class Vehicle:
def __init__(self, fare):
self.fare = fare
def __add__(self, other)://using the special function __add__ operator
return self.fare+ other.fare

bus= Vehicle(20)
car= Vehicle(30)
total_fare=bus+ car
print(total_fare)

Output:
50
Overloading the special function magically defines everytime we use  plus operator in the object
total_fare=bus+ car  we are going to add their fares.
Method Overloading
Method overloading means a class containing multiple methods with the same name but may have different
arguments. Basically python does not support method overloading, but there are several ways to achieve
method overloading. Though method overloading can be achieved, the last defined methods can only be
usable.
Example:
class Area:
def find_area(self, a=None, b=None):
if a != None and b != None:
print("Rectangle:", (a * b))
elifa != None:
2
4
print("square:", (a * a))
else:
print("No figure assigned")

obj1=Area()
obj1.find_area()
obj1.find_area(10)
obj1.find_area(10,20)

Output
No figure assigned
square: 100
Rectangle: 200

In the above example if no arguments are passed during function call then it will show no value assigned, if
we pass a single argument then it will show the area of square and if 2 values are passed then it will show
the area of rectangle.

ABSTRACT CLASSES
A class is called an Abstract class if it contains one or more abstract methods. An abstract method is a
method that is declared, but contains no implementation. Abstract classes may not be instantiated, and its
abstract methods must be implemented by its subclasses.

An abstract class has some features, as follows:


 An abstract class doesn’t contain all of the method implementations required to work completely,
which means it contains one or more abstract methods. An abstract method is a method that just has a
declaration but does not have a detail implementation.

 An abstract class cannot be instantiated. It just provides an interface for subclasses to avoid code
duplication. It makes no sense to instantiate an abstract class.

 A derived subclass must implement the abstract methods to create a concrete class that fits the
interface defined by the abstract class. Therefore it cannot be instantiated unless all of its abstract
methods are overridden.

Define Abstract Class in Python

Python comes with a module called abc which provides useful stuff for abstract class.
We can define a class as an abstract class by abc.ABC and define a method as an abstract method
by abc.abstractmethod. ABC is the abbreviation of abstract base class.

 There are many built-in ABCs in Python. ABCs for Data structures like Iterator, Generator, Set, mapping
etc. are defined in collections.abc module. The numbers module defines numeric tower which is a collection
of base classes for numeric data types. The 'abc' module in Python library provides the infrastructure for
2
5
defining custom abstract base classes.
'abc' works by marking methods of the base class as abstract. This is done by @absttractmethod decorator. A
concrete class which is a sub class of such abstract base class then implements the abstract base by overriding
its abstract methods.

The abc module defines ABCMeta class which is a metaclass for defining abstract base class. Following
example defines Shape class as an abstract base class using ABCMeta. The shape class has area() method
decorated by abstractmethod.

A Rectangle class now uses above Shape class as its parent and implementing the abstract area() method.
Since it is a concrete class, it can be instantiated and imlementedarea() method can be called.

importabc

classShape(metaclass=abc.ABCMeta):

@abc.abstractmethod

def area(self):

pass

classRectangle(Shape):

def __init__(self,x,y):

self.l= x

self.b=y

def area(self):

returnself.l*self.b

r =Rectangle(10,20)

print('area: ',r.area())

Note the abstract base class may have more than one abstract methods. The child class must implement all of
them failing which TypeError will be raised.
The abc module also defines ABC helper class which can be used instead of ABCMeta class in definition of
abstract base class.

class Shape(abc.ABC):
@abc.abstractmethod
def area(self):
pass
Instead of subclassing from abstract base class, it can be registered as abstract base by register class
2
6
decorator.

classShape(abc.ABC):

@abc.abstractmethod

def area(self):

pass

@Shape.register

classRectangle():

def __init__(self,x,y):

self.l= x

self.b=y

def area(self):

returnself.l*self.b

We may also provide class methods and static methods in abstract base class by decorators
@abstractclassmethod and @abstractstatic method decorators respectively.

EXCEPTION HANDLING

We can make certain mistakes while writing a program that lead to errors when we try to run it. A python
program terminates as soon as it encounters an unhandled error. These errors can be broadly classified into two
classes:
1. Syntax errors
2. Logical errors (Exceptions)

Python Syntax Errors


Error caused by not following the proper structure (syntax) of the language is called syntax error or parsing
error.
Let's look at one example:

>>>if a <3
File "<interactive input>", line 1
if a <3
^
SyntaxError: invalid syntax

2
7
As shown in the example, an arrow indicates where the parser ran into the syntax error.
We can notice here that a colon : is missing in the if statement.

Python Logical Errors (Exceptions)


Errors that occur at runtime (after passing the syntax test) are called exceptions or logical errors.
For instance, they occur when we try to open a file(for reading) that does not exist ( FileNotFoundError), try to
divide a number by zero (ZeroDivisionError), or try to import a module that does not exist (ImportError).
Whenever these types of runtime errors occur, Python creates an exception object. If not handled properly, it
prints a traceback to that error along with some details about why that error occurred.

Python has many built-in exceptions that are raised when your program encounters an error (something in the
program goes wrong).
When these exceptions occur, the Python interpreter stops the current process and passes it to the calling process
until it is handled. If not handled, the program will crash.

For example, let us consider a program where we have a function A that calls function B, which in turn calls
function C. If an exception occurs in function C but is not handled in C, the exception passes to B and then
to A.
If never handled, an error message is displayed and our program comes to a sudden unexpected halt.

Python Built-in Exceptions


There are plenty of built-in exceptions in Python that are raised when corresponding errors occur. We can
view all the built-in exceptions using the built-in local() function as follows:

print(dir(locals()['__builtins__']))

locals()['__builtins__'] will return a module of built-in exceptions, functions, and attributes. dir allows us to list


these attributes as strings.
Some of the common built-in exceptions in Python programming along with the error that cause them are listed below:

Exception Cause of Error

AssertionError Raised when an assert statement fails.

AttributeError Raised when attribute assignment or reference fails.

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

FloatingPointError Raised when a floating point operation fails.

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

ImportError Raised when the imported module is not found.

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

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

KeyboardInterrupt Raised when the user hits the interrupt key (Ctrl+C or Delete).

MemoryError Raised when an operation runs out of memory.

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

NotImplementedError Raised by abstract methods.

OSError Raised when system operation causes system related error.

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


OverflowError
represented.

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


ReferenceError
referent.

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

Raised by next() function to indicate that there is no further item to be


StopIteration
returned by iterator.

SyntaxError Raised by parser when syntax error is encountered.

IndentationError Raised when there is incorrect indentation.

TabError Raised when indentation consists of inconsistent tabs and spaces.

SystemError Raised when interpreter detects internal error.

SystemExit Raised by sys.exit() function.

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

2
9
type.

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


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

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

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

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

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

Raised when a function gets an argument of correct type but improper


ValueError
value.

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

If required, we can also define our own exceptions in Python.


We can handle these built-in and user-defined exceptions in Python
using try, except and finally statements.

Catching Exceptions in Python

In Python, exceptions can be handled using a try statement.


The critical operation which can raise an exception is placed inside the try clause. The code that handles the
exceptions is written in the except clause.
Syntax
Here is simple syntax of try....except...else blocks −
try:
You do your operations here;
......................
except ExceptionI:
If there is ExceptionI, then execute this block.
except ExceptionII:
If there is ExceptionII, then execute this block.
......................
else:
If there is no exception then execute this block.
Here are few important points about the above-mentioned syntax −

3
0
 A single try statement can have multiple except statements. This is useful when the try block contains
statements that may throw different types of exceptions.
 You can also provide a generic except clause, which handles any exception.
 After the except clause(s), you can include an else-clause. The code in the else-block executes if the code
in the try: block does not raise an exception.
 The else-block is a good place for code that does not need the try: block's protection.

We can thus choose what operations to perform once we have caught the exception. Here is a simple example.

# import module sys to get the type of exception


import sys

randomList = ['a', 0, 2]

for entry inrandomList:


try:
print("The entry is", entry)
r = 1/int(entry)
break
except:
print("Oops!", sys.exc_info()[0], "occurred.")
print("Next entry.")
print()
print("The reciprocal of", entry, "is", r)

Output

The entry is a
Oops! <class 'ValueError'> occurred.
Next entry.

The entry is 0
Oops! <class 'ZeroDivisionError'>occured.
Next entry.

The entry is 2
The reciprocal of 2 is 0.5

In this program, we loop through the values of the randomList list. As previously mentioned, the portion that can
cause an exception is placed inside the try block.
If no exception occurs, the except block is skipped and normal flow continues(for last value). But if any
exception occurs, it is caught by the except block (first and second values).

3
1
Here, we print the name of the exception using the exc_info() function inside sys module. We can see
that a causes ValueError and 0 causes ZeroDivisionError.

Python try...finally

We can use a finally: block along with a try: block. The finally block is a place to put any code that must
execute, whether the try-block raised an exception or not. The syntax of the try-finally statement is this –
try:
Youdo your operations here;
......................
Due to any exception,this may be skipped.
finally:
This would always be executed.
......................

Here is an example of file operations to illustrate this.

try:
fh=open("testfile","w")
fh.write("This is my test file for exception handling!!")
finally:
print"Error: can\'t find file or read data"

If you do not have permission to open the file in writing mode, then this will produce the following result –
Error: can't find file or read data

ILLUSTRATIVE PROGRAMS: DEMONSTRATE THE CONCEPT OF CLASS AND OBJECTS.

1. Write a Python class named Circle constructed by a radius and two methods which will compute the
area and the perimeter of a circle.

Sample Program:
classCircle():
def__init__(self, r):
self.radius= r

defarea(self):
returnself.radius**2*3.14

defperimeter(self):
return2*self.radius*3.14

NewCircle=Circle(8)
print(NewCircle.area())
3
2
print(NewCircle.perimeter())

Sample Output:

200.96
50.24

Flowchart:

2. Write a Python class to reverse a string word by word.


Input string : 'hello .py'
Expected Output : '.py hello'

Sample Program:

classpy_solution:
defreverse_words(self, s):
return' '.join(reversed(s.split()))

print(py_solution().reverse_words(‘hello .py’))

Sample Output:

.py hello

Pictorial Presentation

3
3
Flowchart:

3.Write a Python program to import built-in array module and display the namespace of the said
module.

Sample Program:
import array
for name inarray.__dict__:
print(name)

Sample Output:

__name__
__doc__
__package__
__loader__
__spec__

3
4
__array_reconstructor
ArrayType
array
typecodes

4.Create a Vehicle class with max_speed and mileage instance attributes

Sample Program:
class Vehicle:
def __init__(self, max_speed, mileage):
self.max_speed = max_speed
self.mileage = mileage

modelX = Vehicle(240, 18)


print(modelX.max_speed,modelX.mileage)

Sample Output:
240 18

5. Create a child class Bus that will inherit all of the variables and methods of the Vehicle class

Sample Program
class Vehicle:

def __init__(self, name, max_speed, mileage):


self.name = name
self.max_speed = max_speed
self.mileage = mileage

class Bus(Vehicle):
pass

School_bus = Bus("School Volvo", 180, 12)


print("Vehicle Name:", School_bus.name, "Speed:", School_bus.max_speed, "Mileage:", School_bus.mileage)

Sample Output:
Vehicle Name: School Volvo Speed: 180 Mileage: 12

EXERCISES
1. Write a Python class named Rectangle constructed by a length and width and a method which
will compute the area of a rectangle. 
2. Write a Python class which has two methods get_String and print_String. get_Stringaccept a
3
5
string from the user and print_String print the string in upper case. 
3. Create a Bus child class that inherits from the Vehicle class. The default fare charge of any
vehicle is seating capacity * 100. If Vehicle is Bus instance, we need to add an extra 10% on full
fare as a maintenance charge. So total fare for bus instance will become the final amount = total
fare + 10% of the total fare.
4. Write a Python class to implement pow(x, n). 
5. Create two new vehicles called car1 and car2 that inherits from Vehicles class. Set car1 to be a red
convertible worth $60,000.00 with a name of Fer, and car2 to be a blue van named Jump worth
$10,000.00.

3
6

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy