Você está na página 1de 37

Access Modifiers in Python

Public:
The access level of a public modifier is everywhere. It can be
accessed from within the class, outside the class, within the
package and outside the package.
Private:
The access level of a private modifier is only within the class. It
cannot be accessed from outside the class.
Protected:
The access level of a protected modifier is within the package
and outside the package through child class. If you do not make the
child class, it cannot be accessed from outside the package.

Public Access Modifier

By default, all the variables and member functions of a class are public in
a python program.
class Employee:
# constructor
def __init__(self, name, sal):
self.name = name
self.sal = sal

All the member variables of the class in the above code will be by
default public, hence we can access them as follows:

>> emp = Employee("Captain", 10000)


>> emp.sal
Private Access Modifier
While the addition of prefix __ (double underscore) results in a
member variable or function becoming private.
# defining class Employee

class Employee:
def __init__(self, name, sal):
self.__name = name # private attribute
self.__sal = sal # private attribute

If we want to access the private member variable, we will get an error.

>>> emp = Employee("Bill", 10000)


>>> emp.__sal
Protected Access Modifier
According to Python convention adding a prefix _(single underscore)
to a variable name makes it protected. Yes, no additional keyword
required.
# defining a class Employee

class Employee:
# constructor
def __init__(self, name, sal):
self._name = name ……….# protected attribute
self._sal = sal …………… # protected attribute

In the code above we have made the class


variables name and sal protected by adding an _ (underscore) as a
prefix, so now we can access them as follows:

>>> emp = Employee("Captain", 10000)


>>> emp._sal
10000

Similarly if there is a child class extending the class Employee then


it can also access the protected member variables of the class Employee.
Let's have an example:
# defining a child class

class HR(Employee):
# member function task
def task(self):
print"We manage Employees"

Now let's try to access protected member variable of class Employee from
the class HR:

>>> hrEmp = HR("Captain", 10000)


>>> hrEmp._sal
10000
>>> hrEmp.task()
We manage Employees
Access modifires example public, private, protected

# define parent class Company

class Company:
# constructor
def __init__(self, name, proj):
self.name = name # name(name of company) is public
self._proj = proj # proj(current project) is protected

# public function to show the details


def show(self):
print("The code of the company is = ",self.ccode)

# define child class Emp


class Emp(Company):
# constructor
def __init__(self, eName, sal, cName, proj):
# calling parent class constructor
Company.__init__(self, cName, proj)
self.name = eName # public member variable
self.__sal = sal # private member variable

# public function to show salary details


def show_sal(self):
print("The salary of ",self.name," is ",self.__sal,)

# creating instance of Company class


c = Company("Stark Industries", "Mark 4")
# creating instance of Employee class
e = Emp("Steve", 9999999, c.name, c._proj)

print("Welcome to ", c.name)


print("Here",e.name,"is working on",e._proj)

# to show the value of __sal we have created a public function show_sal()


e.show_sal()
OOPs Concept
Object-oriented programming (OOP) is a programming
paradigm based on the concept of "objects", which may contain data, in
the form of fields, often known as attributes; and code, in the form of
procedures, often known as methods. For example, a person is an object
which has certain properties such as height, gender, age, etc. It also has
certain methods such as move, talk, and so on.
OOPs concept is use to make powerful, robust and secure
programming instructions.
With any language reference there are only three basic object oriented
concept.

1. Encapsulation and data abstraction


2. Inheritence
3. Polymorphism
Advantages of OOPs

 Real world programming


 Ability to simulate real world event much more effectively.
 Reusable of code
 Information hiding
 Programmers are able to reach their goals faster.

OOPs Concept:
Class
Object
Encapsulation
Data abstraction
Inheritance
Polymorphism
___init___ :-
“___init___” method is reversed method in python class it is called as
constructor in object oriented terminology. This method is called when
object is created from a class and it allows the class to initialize attributes
of class.

Self :
The word “self” is used to represent instance of class by using the
“self” keyword we access the attributes and method of class in python.

Class:
 The class is a group of similar entities.
 It is only an logical component and not the physical entity.
 Class is blueprint, template or prototype of object.
 Class is collection of object.

Ex. 1) student
Properties: name, rollno, Date of Birth
Task Performed : raed( ),write( ), play( )

Object:
 Object is real world entity that has properties and it perform
different task.
 Object is an instance of class.
Ex.
1) Human
Properties: name, color, height
Task perform: walk( ), run( ),read( ),write( )

2) Pen
Properties: Shape, Color
Task perform: write( )
Built-in class attributes
Along with the other attributes, a python class also contains some
built-in class attributes which provide information about the class.

The built-in class attributes are given in the below table.

SN Attribute Description
1 __dict__ It provides the dictionary containing the information
about the class namespace.
2 __doc__ It contains a string which has the class
documentation
3 __name__ It is used to access the class name.

4 __module__ It is used to access the module in which, this class


is defined.
5 __bases__ It contains a tuple including all base classes.

Example:
class Student:
def __init__(self,name,id,age):
self.name = name;
self.id = id;
self.age = age
def display_details(self):
print("Name:%s, ID:%d, age:%d"%(self.name,self.id))
s = Student("John",101,22)
print(s.__doc__)
print(s.__dict__)
print(s.__module__)

Output:

None
{'name': 'John', 'id': 101, 'age': 22}
__main__
Python In-built class functions
The in-built functions defined in the class are described in the following
table.

SN Function Description
1 getattr(obj,name,default) It is used to access the attribute of
the object.
2 setattr(obj, name,value) It is used to set a particular value to
the specific attribute of an object.
3 delattr(obj, name) It is used to delete a specific attribute.

4 hasattr(obj, name) It returns true if the object contains


some specific attribute.

Example:

class Student:
def __init__(self,name,id,age):
self.name = name;
self.id = id;
self.age = age
s = Student("John",101,22) #creates the object of the class Student
print(getattr(s,'name')) #prints the attribute name of the object s
setattr(s,"age",23) # reset the value of attribute age to 23
print(getattr(s,'age')) # prints the modified value of age
print(hasattr(s,'id')) # prints true if the student contains the attribute with name id
delattr(s,'age') # deletes the attribute age
print(s.age) # this will give an error since the attribute age has been deleted

Output:
John
23
True
AttributeError: 'Student' object has no attribute 'age'
#Illustration of creating a class

class Student:
'A student class'
stuCount = 0

def __init__(self, name, rollno): #initialization or constructor method of class Student


self.name = name
self.rollno = rollno
Student.stuCount += 1

def displayCount(self): #displayCount method of class Student


print ("Total Students %d", Student.stuCount)

def displayStudent(self): #displayStduent method of class student

print ("Name : ", self.name, ", Rollno: ", self.rollno)

stu1=Student('John', 111) #first object of class student


stu2=Student('Clara', 112) #second object of class student
stu1.displayStudent()
stu2.displayStudent()
print('total no. of students:', Student.stuCount)
#Illustration of creating a class in Python with input from the user

class Student:
'A student class'
stuCount = 0
def __init__(self): #initialization or constructor method of class
student
self.name=input('enter student name:')
self.rollno=input('enter student rollno:')
Student.stuCount += 1

def displayStudent(self): #displayStduent method of class Student


print ("Name : ", self.name, ", Rollno: ", self.rollno)

stu1=Student()
stu2=Student()
stu3=Student()
stu1.displayStudent()
stu2.displayStudent()
stu3.displayStudent()
print('total no. of students:', Student.stuCount)
Encapsulation:
Binding (or wrapping) code and data together into a single unit is
known as encapsulation.
Wrapping of data.
Binding data and function into on single entity.
In python, prevent data from direct modification which is called
encapsulation.
In python, we denote attribute using underscore as prefix
Single underscore ( _ )  for protected
Double underscore ( _ _ )  for private
A class is an example of encapsulation as it encapsulates all the
data that is member functions, variables, etc.

Consider a real-life example of encapsulation, in a company, there are


different sections like the accounts section, finance section, sales section etc. The
finance section handles all the financial transactions and keeps records of all the data
related to finance. Similarly, the sales section handles all the sales-related activities
and keeps records of all the sales. Now there may arise a situation when for some
reason an official from the finance section needs all the data about sales in a particular
month.
In this case, he is not allowed to directly access the data of the sales
section. He will first have to contact some other officer in the sales section and then
request him to give the particular data. This is what encapsulation is. Here the data of
the sales section and the employees that can manipulate them are wrapped under a
single name “sales section”. As using encapsulation also hides the data. In this
example, the data of any of the sections like sales, finance or accounts are hidden
from any other section.
To demonstrate encapsulation

Private ( “ __ “) double underscore

class computer:
def __init__(self):
self.__maxspeed=120
def sell(self):
print("Maximum speed:",self.__maxspeed)
def setter(self,price): #setter function
self.__maxspeed=price

q=computer()
q.sell()
q.__maxspeed=150 # value change but value not change because of encapsulation
q.sell()
q.setter(200) # change value using setter function
q.sell()
Output:

Maximum speed: 120


Maximum speed: 120
Maximum speed: 200
To demonstrate encapsulation

Protected ( “ _ “ ) single underscore

# Creating a base class


class Base:
def __init__(self):
# Protected member
self._a = 2

# Creating a derived class


class Derived(Base):
def __init__(self):
# Calling constructor of
# Base class
Base.__init__(self)
print("Calling protected member of base class: ")
print(self._a)

obj1 = Base()

obj2 = Derived()

Output:
Calling protected member of base class:
2
Abstraction :
Abstraction is a process of hiding the implementation details and
Showing only functionality to the user.
Another way, it shows only essential things to the user and hides the
internal details.
for example,
1) Sending SMS where you type the text and send the message. You
don't know the internal processing about the message delivery.

2) Withdraw money from ATM you simply insert card and click some
button and get money but we don’t know their background
process.

Abstract class

A class which is declared as abstract is known as an abstract


class. It can have abstract and non-abstract methods. It needs to be
extended and its method implemented. It cannot be instantiated.

Points to Remember
o An abstract class must be declared with an abstract keyword.
o It can have abstract and non-abstract methods.
o It cannot be instantiated.
o It can have constructors and static methods also.
o It can have final methods which will force the subclass not to change
the body of the method.

Abstract Method
A method which is declared as abstract and does not have
implementation is known as an abstract method.
To demonstrate abstraction using abstract class

from abc import ABC, abstractmethod


class Payment(ABC):
def print_slip(self, amount):
print('Purchase of amount- ', amount)
def payment(self, amount):
pass
class CreditCardPayment(Payment):
def payment(self, amount):
print('Credit card payment of- ', amount)

class MobileWalletPayment(Payment):
def payment(self, amount):
print('Mobile wallet payment of- ', amount)

obj = CreditCardPayment()
obj.payment(100)
obj.print_slip(100)
obj = MobileWalletPayment()
obj.payment(200)
obj.print_slip(200)

In above example there is an abstract class Payment that has an


abstract method payment(). There are two child classes
CreditCardPayment and MobileWalletPayment derived from Payment
that implement the abstract method payment() as per their functionality.

As a user we are abstracted from that implementation when an


object of CreditCardPayment is created and payment() method is invoked
using that object, payment method of CreditCardPayment class is
invoked. When an object of MobileWalletPayment is created and
payment() method is invoked using that object, payment method of
MobileWalletPayment class is invoked.
To demonstrate abstraction

from abc import ABC,abstractmethod


class Person(ABC):
def eat(self):
pass
class Rtan(Person):
def eat(self):
print("S-idly")
class Durga(Rtan):
def eat(self):
print("d-idly")
r=Rtan()
r.eat()
d=Durga()
d.eat()

To demonstrate abstraction

from abc import ABC,abstractmethod


class A(ABC):
def __init__(self,value):
self.value=value

def disp(self):
pass
class Add(A):
def disp(self):
print(self.value)
class Mul(A):
def disp(self):
print(10*self.value)
a=Add(10)
b=Mul(5)
a.disp()
b.disp()
Inheritance:
Inheritance is a mechanism in which one class acquires the property
of another class. The new class is known as a derived class or child
class, and the one whose properties are acquired is known as a base
class or parent class.

Single Inheritance:

When a child class inherits from only one parent class, it is called
as single inheritance
Multiple Inheritance:

When a child class inherits from multiple parent classes, it is


called as multiple inheritance.

Multilevel Inheritance :

one class can inherit from a derived class. Hence, the derived class
becomes the base class for the new class.

OR

When we have child and grand child relationship.


Hierarchical Inheritance:

One class is inherited by many sub classes.

In another way, One base class is inherited by many derived classes.

Hybrid inheritance :

It is a combination of Single and Multiple inheritance.

As per above example, all the public and protected members of


Class A are inherited into Class D, first via Class B and secondly via
Class C.
#Illustration of single inheritance

class shape: #base class


'A shape class'
def __init__(self): #constructor method of base class
self.length = float(input('Enter Length:'))
self.breadth = float(input('Enter Breadth:'))

def display(self): #display method of base class


print ("\nLength: ", self.length)
print ("\nBreadth: ", self.breadth)

class rectangle(shape): #derived class


'A rectangle class'
def __init__(self): #constructor method of derived class
shape.__init__(self)
self.area=0
def compute_area(self): #compute_srea funciton of derived
class
self.area = self.length*self.breadth
print("\nArea of rectangle=", self.area)

r1=rectangle() # object of derived class


r1.display()
r1.compute_area()
#Illustration of multiple inheritance

class student: #base class 1


'A student class'
def __init__(self): #constructor method of base class 1
self.name = (input('Enter Student Name:'))
self.rollno = int(input('Enter RollNo:'))

def display(self): #display method of base class 1


print ("\nName: ", self.name)
print ("\nRollNo: ", self.rollno)

class marks: #base class 2


'A marks class'
def __init__(self): #constructor method of base class 2
self.m1 = float(input('Enter marks of subject 1:'))
self.m2 = float(input('Enter marks of subject 2:'))
self.m3 = float(input('Enter marks of subject 3:'))
def display_marks(self): #display function of base class 2
print("\nMarks of subject 1=", self.m1)
print("\nMarks of subject 2=", self.m2)
print("\nMarks of subject 3=", self.m3)

class result(student, marks): #derived class


'A result class'
def __init__(self): #constructor method of derived class
student.__init__(self)
marks.__init__(self)
self.total_marks = self.m1 + self.m2 + self.m3
self.perc = self.total_marks*100/300
def display_result(self): #display_result function of derived class
print("\nTotal Marks:", self.total_marks)
print("\nPercentage:", self.perc)

r1=result() # object of derived class result


r1.display()
r1.display_marks()
r1.display_result()
#Illustration of multilevel inheritance

class student: #base class


'A student class'
def __init__(self): #constructor method of base class
self.name = (input('Enter Student Name:'))
self.rollno = int(input('Enter RollNo:'))

def display(self): #display method of base class


print ("\nName: ", self.name)
print ("\nRollNo: ", self.rollno)

class marks(student): #derived class


'A marks class'
def __init__(self): #constructor method of derived
class
self.m1 = float(input('Enter marks of subject 1:'))
self.m2 = float(input('Enter marks of subject 2:'))
self.m3 = float(input('Enter marks of subject 3:'))
def display_marks(self): #display function of base class 2
print("\nMarks of subject 1=", self.m1)
print("\nMarks of subject 2=", self.m2)
print("\nMarks of subject 3=", self.m3)

class result(marks): # new derived class


'A result class'
def __init__(self): #constructor method of new
derived class
student.__init__(self)
marks.__init__(self)
self.total_marks = self.m1 + self.m2 + self.m3
self.perc = self.total_marks*100/300
def display_result(self): #display_result function of derived class
print("\nTotal Marks:", self.total_marks)
print("\nPercentage:", self.perc)

r1=result() # object of derived class result


r1.display()
r1.display_marks()
r1.display_result(
Polymorphism:

One task is performed in different way is called polymorphism.

Implementing same method in different context.

Example:-

1)
add (x, y)

add( )

+  addition (arithmetic operation)

+  concatenation ( string)

2)
To demonstrate polymorphism

class duck:
def fly(self):
print("duck can't fly")
def swim(self):
print("duck can swim")

class penguin:
def fly(self):
print("penguin can't fly")
def swim(self):
print("penguin can swim")

def flying_test(bird):
bird.fly()
def swiming_test(bird):
bird.swim()
da=duck()
pe=penguin()
flying_test(da)
flying_test(pe)
swiming_test(pe)
swiming_test(da)
To demonstrate polymorphism using for loop
class India():
def capital(self):
print("Delhi is a capital of India")
def language(self):
print("hindi is primary language")
def type(self):
print("india is develeping country")

class USA():
def capital(self):
print("WS is a capital of India")

def language(self):
print("English is primary language")

def type(self):
print("USA is develeped country")
india=India()
usa=USA()
for country in(india,usa):
country.capital()
country.language()
country.type()
#Polymorphism with inheritance

class Bird:
def intro(self):
print("There are many types of birds")
def flight(self):
print("most of birds can fly but some cannot")
class Sparrow(Bird):
def flight(self):
print("sparrow can fly")
class Ostrich(Bird):
def flight(self):
print("ostrich cannot fly")
bird=Bird()
spa=Sparrow()
ost=Ostrich()
bird.intro()
bird.flight()
spa.intro()
spa.flight()
ost.intro()
ost.flight()
Python Operator Overloading

Operator overloading means to assign a special meaning to the


existing operator to perform some intended task.

In other words, same operator exhibiting different meaning as per the


situation is called operator overloading.

For example,
‘+’ operator which is used with numbers to perform addition operation.
But ‘+’ operator when used with two strings concatenate those Strings and
merge two lists when used with lists in Python. It is possible because ‘+’
operator is overloaded in str and list class to provide extended
functionality.

Magic Method for Operator Overloading


Magic methods in Python are the methods prefixed with two
underscores and suffixed with two underscores. These magic methods
are also known as Dunders (Double Underscores) in Python. In this
section magic methods for some of the important operators are listed.

Magic Method for arithmetic operator

Operator Magic Method Description


+ __add__(self, other) Additive operator
- __sub__(self, other) Subtraction operator
* __mul__(self, other) Multiplication operator
/ __truediv__(self, other) Division with fractional result
% __mod__(self, other) Remainder operator
// __floordiv__(self, other) Division with integer result, discarding any
fractional part
** __pow__(self, other) Return a to the power b, for a and b numbers.
@ __matmul__(self, other) Matrix Multiplication. Available from version
3.5
Magic Method for comparison operator

Operator Magic Method Description


< __lt__(self, other) less than
<= __le__(self, other) less than or equal to
== __eq__(self, other) equal to
!= __ne__(self, other) not equal to
> __gt__(self, other) greater than
>= __ge___(self, other) greater than or equal to

Magic Method for Unary operator

Operator Magic Method Description


+ __pos__(self, other) Unary plus operator; indicates positive
value
- __neg__(self, other) Unary minus operator; negates an
expression
~ __invert__(self, Returns the bitwise inverse of the number
other)
#Illustration of arithmetic plus '+' operator overloading

class complex:
'A complex number class'
def __init__(self, real, imag):
self.real=real
self.imag=imag

def __add__(self, obj): #definition of overloading '+'


operator
real = self.real + obj.real
imag = self.imag + obj.imag
return(complex(real, imag))

def display(self):
print(self.real, "+ i",self.imag)

c1=complex(5,6)
c2=complex(7,8)
c1.display()
c2.display()
c3=c1+c2 #overloading '+' operator call
c3.display()
#Illustration of subtraction '-' operator overloading

class complex:
'A complex number class'
def __init__(self, real, imag):
self.real = real
self.imag = imag

def __sub__(self, obj):


real = self.real - obj.real
imag = self.imag - obj.imag
return(complex(real, imag))

def display(self):
print(self.real, "+ i",self.imag)

c1=complex(5, 8)
c2=complex(6, 7)
c1.display()
c2.display()
c3=c1-c2
c3.display()
#Illustration of relational '>' operator overloading

class distance:
'A distance class'
def __init__(self, a, b):
self.a = a
self.b = b

def __gt__(self, obj):


self.mag = self.a**2 + self.b**2
obj.mag = obj.a**2 + obj.b**2
return(self.mag>obj.mag)

d1=distance(14, 20)
d2=distance(18, 15)
print(d1>d2)
import math

class Circle:

def __init__(self, radius):


self.radius = radius

def get_result(self):
return self.radius

def area(self):
return math.pi * self.radius ** 2

def __add__(self, another_circle):


return Circle(self.radius + another_circle.radius)

def __sub__(self, another_circle):


return Circle(self.radius - another_circle.radius)

def __mul__(self, another_circle):


return Circle(self.radius * another_circle.radius)

def __gt__(self, another_circle):


return Circle(self.radius > another_circle.radius)

def __lt__(self, another_circle):


return Circle(self.radius < another_circle.radius)

def __ge__(self, another_circle):


return Circle(self.radius >= another_circle.radius)

def __le__(self, another_circle):


return Circle(self.radius <= another_circle.radius)

def __eq__(self, another_circle):


return Circle(self.radius == another_circle.radius)

def __ne__(self, another_circle):


return Circle(self.radius != another_circle.radius)
c1 = Circle(10)
print(c1.get_result())
print(c1.area())

c2 = Circle(15)
print(c2.get_result())
print(c1.area())

c3 = c1 + c2
print(c3.get_result())

c3 = c2 - c1
print(c3.get_result())

c4 = c1 * c2
print(c4.get_result())

c5 = c1 < c2
print(c5.get_result())

c5 = c2 < c1
print(c5.get_result())
Method Overriding
We can provide some specific implementation of the parent class
method in our child class. When the parent class method is defined in
the child class with some specific implementation, then the concept
is called method overriding. We may need to perform method overriding
in the scenario where the different definition of a parent class method is
needed in the child class.

Consider the following example to perform method overriding in python.

class Bank:
def getroi(self):
return 10;
class SBI(Bank):
def getroi(self):
return 7;
class ICICI(Bank):
def getroi(self):
return 8;
b1 = Bank()
b2 = SBI()
b3 = ICICI()
print("Bank Rate of interest:",b1.getroi());
print("SBI Rate of interest:",b2.getroi());
print("ICICI Rate of interest:",b3.getroi());
Python Constructor

A constructor is a special type of method (function) which is used to


initialize the instance members of the class.

Constructors can be of two types.

1. Parameterized Constructor
2. Non-parameterized Constructor

Constructor definition is executed when we create the object of this


class. Constructors also verify that there are enough resources for the
object to perform any start-up task.

Creating the constructor in python

In python, the method __init__ simulates the constructor of the class.


This method is called when the class is instantiated. We can pass any
number of arguments at the time of creating the class object, depending
upon __init__ definition. It is mostly used to initialize the class attributes.
Every class must have a constructor, even if it simply relies on the default
constructor.

Parameterized Constructor :

A Constructor with arguments is known as Parameterized


constructor.

Non-parameterized Constructor/Default Constructor:

The constructors that have an empty parameter are known as non-


parameterized constructors.
# Example of Parameterized Constructor

class Student:
def __init__(self,name,major,gpa):
self.name=name
self.major=major
self.gpa=gpa

def is_on(self):
if self.gpa>3.5:
return Pass
else:
return Fail
s=student(“Vicky”,”xyz”,5.6)
print(s.is_on())

# Example of non parameterized Constructor

class Student:
# Constructor - non parameterized
def __init__(self):
print("This is non parametrized constructor")
def show(self,name):
print("Hello",name)
student = Student()
student.show("John")
Special Function in Python

The issubclass(sub,sup) method

The issubclass(sub, sup) method is used to check the relationships between the
specified classes. It returns true if the first class is the subclass of the second class,
and false otherwise. Consider the following example.

class Calculation1:
def Summation(self,a,b):
return a+b;
class Calculation2:
def Multiplication(self,a,b):
return a*b;
class Derived(Calculation1,Calculation2):
def Divide(self,a,b):
return a/b;
d = Derived()
print(issubclass(Derived,Calculation2))
print(issubclass(Calculation1,Calculation2))
*************Output*************************
True
False

The isinstance (obj, class) method


The isinstance() method is used to check the relationship between the objects
and classes. It returns true if the first parameter, i.e., obj is the instance of the second
parameter, i.e., class. Consider the following example.
class Calculation1:
def Summation(self,a,b):
return a+b;
class Calculation2:
def Multiplication(self,a,b):
return a*b;
class Derived(Calculation1,Calculation2):
def Divide(self,a,b):
return a/b;
d = Derived()
print(isinstance(d,Derived))

*************************Output*******************
True