Python Unit 5
Python Unit 5
Create a Class
Example
class MyClass:
x=5
Create Object
Example
p1 = MyClass()
print(p1.x)
The examples above are classes and objects in their simplest form, and are not really useful
in real life applications.
To understand the meaning of classes we have to understand the built-in __init__() function.
All classes have a function called __init__(), which is always executed when the class is
being initiated.
Use the __init__() function to assign values to object properties, or other operations that are
necessary to do when the object is being created:
Example
Create a class named Person, use the __init__() function to assign values for name and age:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p1 = Person("John", 36)
print(p1.name)
print(p1.age)
Note: The __init__() function is called automatically every time the class is being used to
create a new object.
Object Methods
Objects can also contain methods. Methods in objects are functions that belong to the object.
Example
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def myfunc(self):
print("Hello my name is " + self.name)
p1 = Person("John", 36)
p1.myfunc()
Note: The self parameter is a reference to the current instance of the class, and is used to
access variables that belong to the class.
The self Parameter
The self parameter is a reference to the current instance of the class, and is used to access
variables that belongs to the class.
It does not have to be named self , you can call it whatever you like, but it has to be the first
parameter of any function in the class:
Example
class Person:
def __init__(mysillyobject, name, age):
mysillyobject.name = name
mysillyobject.age = age
def myfunc(abc):
print("Hello my name is " + abc.name)
p1 = Person("John", 36)
p1.myfunc()
Example
p1.age = 40
Example
del p1.age
Delete Objects
Example
del p1
class definitions cannot be empty, but if you for some reason have a class definition with no
content, put in the pass statement to avoid getting an error.
Example
class Person:
pass
Local Scope
A variable created inside a function belongs to the local scope of that function, and can only
be used inside that function.
Example
def myfunc():
x = 300
print(x)
myfunc()
Example
The local variable can be accessed from a function within the function:
def myfunc():
x = 300
def myinnerfunc():
print(x)
myinnerfunc()
myfunc()
Global Scope
A variable created in the main body of the Python code is a global variable and belongs to
the global scope.
Global variables are available from within any scope, global and local.
Example
x = 300
def myfunc():
print(x)
myfunc()
print(x)
Naming Variables
If you operate with the same variable name inside and outside of a function, Python will treat
them as two separate variables, one available in the global scope (outside the function) and
one available in the local scope (inside the function):
Example
The function will print the local x, and then the code will print the global x:
x = 300
def myfunc():
x = 200
print(x)
myfunc()
print(x)
Global Keyword
If you need to create a global variable, but are stuck in the local scope, you can use
the global keyword.
Example
If you use the global keyword, the variable belongs to the global scope:
def myfunc():
global x
x = 300
myfunc()
print(x)
Also, use the global keyword if you want to make a change to a global variable inside a
function.
Example
To change the value of a global variable inside a function, refer to the variable by using
the global keyword:
x = 300
def myfunc():
global x
x = 200
myfunc()
print(x)
When the user uses the operator on the user-defined data types of class, then a magic
function that is associated with the operator will be invoked automatically. The process of
changing the behaviour of the operator is as simple as the behaviour of the function or
method defined.
The user define methods or functions in the class and the operator works according to that
behaviour defined in the functions. When the user uses the "+" operator, it will change the
code of a magic function, and the user has an extra meaning of the "+" operator.
Program : Simply adding two objects.
Python program for simply using the overloading operator for adding two objects.
Example:
class example:
1. def __init__(self, X):
2. self.X = X
3.
4. # adding two objects
5. def __add__(self, U):
6. return self.X + U.X
7. object_1 = example( int( input( print ("Please enter the value: "))))
8. object_2 = example( int( input( print ("Please enter the value: "))))
9. print (": ", object_1 + object_2)
10.object_3 = example(str( input( print ("Please enter the value: "))))
11.object_4 = example(str( input( print ("Please enter the value: "))))
12.print (": ", object_3 + object_4)
Output:
Please enter the value: 23
Please enter the value: 21
: 44
Please enter the value: Good
Please enter the value: Morning
: GoodMorning
Python pickle
Python pickle module is used for serializing and de-serializing a Python object structure.
Any object in Python can be pickled so that it can be saved on disk. What pickle does is that
it “serializes” the object first before writing it to file. Pickling is a way to convert a python
object (list, dict, etc.)
In Python, pickling is the process by which Python objects are converted to byte
streams. Pickling is about serializing the object structure in python.
Python pickle module is used for serializing and de-serializing python object structures. The
process to converts any kind of python objects (list, dict, etc.) into byte streams (0s and 1s)
is called pickling or serialization or flattening or marshalling. We can converts the byte
stream (generated through pickling) back into python objects by a process called as
unpickling.
Why Pickle?: In real world sceanario, the use pickling and unpickling are widespread as
they allow us to easily transfer data from one server/system to another and then store it in a
file or database.
Precaution: It is advisable not to unpickle data received from an untrusted source as they
may pose security threat. However, the pickle module has no way of knowing or raise alarm
while pickling malicious data.
Only after importing pickle module we can do pickling and unpickling. Importing pickle can
be done using the following command −
import pickle
Pickle examples:
Pickle a simple dictionary −
import pickle
EmpID={1:"Zack",2:"53050",3:"IT",4:"38",5:"Flipkart"}
pickling_on=open("EmpID.pickle","wb")
pickle.dump(EmpID,pickling_on)
pickling_on.close()
Unpickle a dictionary −
import pickle
pickle_off=open("EmpID.pickle",'rb')
EmpID=pickle.load(pickle_off)
print(EmpID)
On running above script(unpickle) we get our dictionary back as we initialized earlier. Also,
please note because we are reading bytes here, we have used “rb” instead of “r”.
Output
{1: 'Zack', 2: '53050', 3: 'IT', 4: '38', 5: 'Flipkart'}
Pickle Exceptions
Below are some of the common exceptions raised while dealing with pickle module −
Pickle.PicklingError: If the pickle object doesn’t support pickling, this exception is
raised.
Pickle.UnpicklingError: In case the file contains bad or corrupted data.
EOFError: In case the end of file is detected, this exception is raised.
Prons:
Comes handy to save complicated data.
Easy to use, lighter and doesn’t require several lines of code.
The pickled file generated is not easily readable and thus provide some security.
Cons:
Languages other than python may not able to reconstruct pickled python objects.
Risk of unpickling data from malicious sources.
The else block lets you execute code when there is no error.
The finally block lets you execute code, regardless of the result of the try- and except blocks.
Exception Handling
When an error occurs, or exception as we call it, Python will normally stop and generate an
error message.
Example
try:
print(x)
except:
print("An exception occurred")
Since the try block raises an error, the except block will be executed.
Without the try block, the program will crash and raise an error:
Example
print(x)
Many Exceptions
You can define as many exception blocks as you want, e.g. if you want to execute a special
block of code for a special kind of error:
Example
Print one message if the try block raises a NameError and another for other errors:
try:
print(x)
except NameError:
print("Variable x is not defined")
except:
print("Something else went wrong")
Else
You can use the else keyword to define a block of code to be executed if no errors were
raised:
Example
In this example, the try block does not generate any error:
try:
print("Hello")
except:
print("Something went wrong")
else:
print("Nothing went wrong")
Finally
The finally block, if specified, will be executed regardless if the try block raises an error or
not.
Example
try:
print(x)
except:
print("Something went wrong")
finally:
print("The 'try except' is finished")
Example
try:
f = open("demofile.txt")
try:
f.write("LorumIpsum")
except:
print("Something went wrong when writing to the file")
finally:
f.close()
except:
print("Something went wrong when opening the file")
The program can continue, without leaving the file object open.
Raise an exception
Example
Raise an error and stop the program if x is lower than 0:
x = -1
if x < 0:
raise Exception("Sorry, no numbers below zero")
You can define what kind of error to raise, and the text to print to the user.
Example
x = "hello"
Python 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.
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):
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()
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 you 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()
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).
Note: The __init__() function is called automatically every time the class is being used to
create a new object.
Example
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:
Example
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.
Python also has a super() function that will make the child class inherit all the methods and
properties from its parent:
Example
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
Example
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:
Example
Add a year parameter, and pass the correct year when creating objects:
class Student(Person):
def __init__(self, fname, lname, year):
super().__init__(fname, lname)
self.graduationyear = year
Polymorphism
Polymorphism in python defines methods in the child class that have the same name as
the methods in the parent class. In inheritance, the child class inherits the methods from
the parent class. Also, it is possible to modify a method in a child class that it has inherited
from the parent class.
Polymorphism means multiple forms. In python we can find the same operator or function
taking multiple forms. It also useful in creating different classes which will have class
methods with same name. That helps in re using a lot of code and decreases code
complexity. Polymorphism is also linked to inheritance as we will see in some examples
below.
Polymorphism in operators
The + operator can take two inputs and give us the result depending on what the inputs are.
In the below examples we can see how the integer inputs yield an integer and if one of the
input is float then the result becomes a float. Also for strings, they simply get concatenated.
This happens automatically because of the way the + operator is created in python.
Example
a =23
b =11
c =9.5
s1 ="Hello"
s2 ="There!"
print(a + b)
print(type(a + b))
print(b + c)
print(type (b + c))
print(s1 + s2)
print(type(s1 + s2))
Running the above code gives us the following result −
Output
34
20.5
HelloThere!
Polymorphism in in-built functions
We can also see that different python functions can take inputs of different types and then
process them differently. When we supply a string value to len() it counts every letter in it.
But if we five tuple or a dictionary as an input, it processes them differently.
Example
str='Hi There !'
tup=('Mon','Tue','wed','Thu','Fri')
lst=['Jan','Feb','Mar','Apr']
dict={'1D':'Line','2D':'Triangle','3D':'Sphere'}
print(len(str))
print(len(tup))
print(len(lst))
print(len(dict))
Running the above code gives us the following result −
Output
10
5
4
3
Polymorphism in user-defined methods
We can create methods with same name but wrapped under different class names. So we can
keep calling the same method with different class name pre-fixed to get different result. In
the below example we have two classes, rectangle and circle to get their perimeter and area
using same methods.
Example
from math import pi
classRectangle:
def __init__(self, length, breadth):
self.l= length
self.b= breadth
def perimeter(self):
return2*(self.l+self.b)
def area(self):
returnself.l*self.b
classCircle:
def __init__(self, radius):
self.r= radius
def perimeter(self):
return2* pi *self.r
def area(self):
return pi *self.r**2
Abstract class
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.
Abstract base classes provide a way to define interfaces when other techniques like hasattr()
would be clumsy or subtly wrong (for example with magic methods). ABCs introduce
virtual subclasses, which are classes that don’t inherit from a class but are still recognized by
isinstance() and issubclass() functions. 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
defining custom abstract base classes.
class Polygon(ABC):
@abstractmethod
def noofsides(self):
pass
class Triangle(Polygon):
class Pentagon(Polygon):
def noofsides(self):
class Hexagon(Polygon):
def noofsides(self):
class Quadrilateral(Polygon):
def noofsides(self):
# Driver code
R = Triangle()
R.noofsides()
K = Quadrilateral()
K.noofsides()
R = Pentagon()
R.noofsides()
K = Hexagon()
K.noofsides()
Output:
I have 3 sides
I have 4 sides
I have 5 sides
I have 6 sides
Event-driven programming
Event-driven programming is a paradigm of system architecture where the logic flow
within the program is driven by events such as user actions, messages from other
programs, or hardware (sensor) inputs.
Event-driven programming focuses on events. Eventually, the flow of program depends upon
events. Until now, we were dealing with either sequential or parallel execution model but the
model having the concept of event-driven programming is called asynchronous model.
Event-driven programming depends upon an event loop that is always listening for the new
incoming events. The working of event-driven programming is dependent upon events. Once
an event loops, then events decide what to execute and in what order. Following flowchart
will help you understand how this works −
Python Module – Asyncio
Asyncio module was added in Python 3.4 and it provides infrastructure for writing single-
threaded concurrent code using co-routines. Following are the different concepts used by the
Asyncio module −
The event loop
Event-loop is a functionality to handle all the events in a computational code. It acts round
the way during the execution of whole program and keeps track of the incoming and
execution of events. The Asyncio module allows a single event loop per process. Followings
are some methods provided by Asyncio module to manage an event loop −
loop = get_event_loop() − This method will provide the event loop for the current
context.
loop.call_later(time_delay,callback,argument) − This method arranges for the
callback that is to be called after the given time_delay seconds.
loop.call_soon(callback,argument) − This method arranges for a callback that is to
be called as soon as possible. The callback is called after call_soon() returns and when
the control returns to the event loop.
loop.time() − This method is used to return the current time according to the event
loop’s internal clock.
asyncio.set_event_loop() − This method will set the event loop for the current context
to the loop.
asyncio.new_event_loop() − This method will create and return a new event loop
object.
loop.run_forever() − This method will run until stop() method is called.
Example
The following example of event loop helps in printing hello world by using the
get_event_loop() method. This example is taken from the Python official docs.
importasyncio
defhello_world(loop):
print('Hello World')
loop.stop()
loop=asyncio.get_event_loop()
loop.call_soon(hello_world, loop)
loop.run_forever()
loop.close()
Output
Hello World