Object
Oriented Programming in Python
Below is a simple Python program
that creates a class with single method.
|
# A simple example class
class Test:
# A sample method
def
fun(self):
print("Hello")
# Driver code
obj = Test()
obj.fun()
|
Output:
Hello
As we can see above, we create a new
class using the class statement and the name of the class. This is followed by
an indented block of statements which form the body of the class. In this case,
we have defined a single method in the class.
Next, we create an object/instance
of this class using the name of the class followed by a pair of parentheses.
The
self
1. Class methods must have an extra first parameter in method
definition. We do not give a value for this parameter when we call the method,
Python provides it
2. If we have a method which takes no arguments, then we still
have to have one argument – the self. See fun() in above simple example.
3. This is similar to this pointer in C++ and this reference in
Java.
When we call a method of this object
as myobject.method(arg1, arg2), this is automatically converted by Python into
MyClass.method(myobject, arg1, arg2) – this is all the special self is about.
The
__init__ method
The __init__ method is similar to constructors in C++ and Java. It is run as soon as an object of a class is instantiated. The method is useful to do any initialization you want to do with your object.
The __init__ method is similar to constructors in C++ and Java. It is run as soon as an object of a class is instantiated. The method is useful to do any initialization you want to do with your object.
|
# A Sample class with init method
class Person:
# init method or constructor
def
__init__(self, name):
self.name
= name
# Sample Method
def
say_hi(self):
print('Hello,
my name is', self.name)
p = Person('Shwetanshu')
p.say_hi()
|
Output:
Hello, my name is Shwetanshu
Here, we define the __init__ method
as taking a parameter name (along with the usual self). .
Class
and Instance Variables (Or attributes)
In Python, instance variables are variables whose value is assigned inside a constructor or method with self.
In Python, instance variables are variables whose value is assigned inside a constructor or method with self.
Class variables are variables whose
value is assigned in class.
|
# Python program to show that the variables with a
value
# assigned in class declaration, are class variables and
# variables inside methods and constructors are instance
# variables.
# Class for Computer Science Student
class CSStudent:
# Class Variable
stream = 'cse'
# The init method or constructor
def
__init__(self, roll):
# Instance
Variable
self.roll
= roll
# Objects of CSStudent class
a = CSStudent(101)
b = CSStudent(102)
print(a.stream) # prints "cse"
print(b.stream) # prints "cse"
print(a.roll) # prints 101
# Class variables can be accessed using class
# name also
print(CSStudent.stream) # prints
"cse"
|
We can define instance variables
inside normal methods also.
|
# Python program to show that we can create
# instance variables inside methods
# Class for Computer Science Student
class CSStudent:
# Class Variable
stream = 'cse'
# The init method or constructor
def
__init__(self, roll):
# Instance
Variable
self.roll
= roll
# Adds an instance variable
def
setAddress(self, address):
self.address
= address
# Retrieves instance
variable
def
getAddress(self):
return self.address
# Driver Code
a = CSStudent(101)
a.setAddress("Noida, UP")
print(a.getAddress())
|
Output :
Noida, UP
|
# An empty class
class Test:
pass
|
Data hiding
In Python, we use
double underscore (Or __) before the attributes name and those attributes will
not be directly visible outside.
|
class MyClass:
# Hidden member of MyClass
__hiddenVariable = 0
# A member method that
changes
# __hiddenVariable
def
add(self, increment):
self.__hiddenVariable
+= increment
print (self.__hiddenVariable)
# Driver code
myObject = MyClass()
myObject.add(2)
myObject.add(5)
# This line causes error
print (myObject.__hiddenVariable)
|
Output :
2
7
Traceback (most recent call last):
File
"filename.py", line 13, in
print
(myObject.__hiddenVariable)
AttributeError: MyClass instance has
no attribute '__hiddenVariable'
In the above program, we tried to
access hidden variable outside the class using object and it threw an
exception.
We can access the value of hidden
attribute by a tricky syntax:
|
# A Python program to demonstrate that hidden
# members can be accessed outside a class
class MyClass:
# Hidden member of MyClass
__hiddenVariable = 10
# Driver code
myObject = MyClass()
print(myObject._MyClass__hiddenVariable)
|
Output :
10
Private
methods are accessible outside their class, just not easily accessible. Nothing in Python is truly private; internally, the
names of private methods and attributes are mangled and unmangled on the fly to
make them seem inaccessible by their given names [See this for
source ].
Printing Objects
Printing objects gives us information about objects we are working with. In C++, we can do this by adding a friend ostream& operator << (ostream&, const Foobar&) method for the class. In Java, we use toString() method. In python this can be achieved by using __repr__ or __str__ methods.
|
class Test:
def
__init__(self, a, b):
self.a = a
self.b = b
def
__repr__(self):
return "Test a:%s b:%s" %
(self.a, self.b)
def
__str__(self):
return "From str method of Test: a
is %s," \
"b
is %s" % (self.a, self.b)
# Driver
Code
t = Test(1234,
5678)
print(t) # This calls __str__()
print([t]) # This calls __repr__()
|
Output :
From str method of Test: a is 1234,b is 5678
[Test a:1234 b:5678]
Important
Points about Printing:
·
If no __str__ method is defined,
print t (or print str(t)) uses __repr__.
|
class Test:
def
__init__(self, a, b):
self.a = a
self.b = b
def
__repr__(self):
return "Test a:%s b:%s" %
(self.a, self.b)
# Driver
Code
t = Test(1234,
5678)
print(t)
|
Output :
Test a:1234 b:5678
·
If no __repr__ method is defined
then the default is used.
|
class Test:
def
__init__(self, a, b):
self.a = a
self.b = b
# Driver
Code
t = Test(1234,
5678)
print(t)
|
Output :
<__main__.Test instance at 0x7fa079da6710>
Inheritance
One of the major advantages of
Object Oriented Programming is re-use. Inheritance is one of the mechanisms to
achieve the same. In inheritance, a class (usually called superclass) is
inherited by another class (usually called subclass). The subclass adds some
attributes to superclass.
Below is a sample Python program to
show how inheritance is implemented in Python.
|
# A Python program to demonstrate inheritance
# Base or Super class. Note object in bracket.
# (Generally, object is made ancestor of all classes)
# In Python 3.x "class Person" is
# equivalent to "class Person(object)"
class Person(object):
# Constructor
def
__init__(self, name):
self.name
= name
# To get name
def
getName(self):
return self.name
# To check if this person is
employee
def
isEmployee(self):
return False
# Inherited or Sub class (Note Person in bracket)
class Employee(Person):
# Here we return true
def
isEmployee(self):
return True
# Driver code
emp = Person("Geek1") # An Object of Person
print(emp.getName(), emp.isEmployee())
emp = Employee("Geek2") # An Object of Employee
print(emp.getName(), emp.isEmployee())
|
Output:
('Geek1', False)
('Geek2', True)
How
to check if a class is subclass of another?
Python provides a function issubclass() that directly tells us if a class is subclass of another class.
Python provides a function issubclass() that directly tells us if a class is subclass of another class.
|
# Python example to check if a class is
# subclass of another
class Base(object):
pass
# Empty Class
class Derived(Base):
pass
# Empty Class
# Driver Code
print(issubclass(Derived, Base))
print(issubclass(Base, Derived))
d = Derived()
b = Base()
# b is not an instance of Derived
print(isinstance(b, Derived))
# But d is an instance of Base
print(isinstance(d, Base))
|
Output:
True
False
False
True
What
is object class?
Like Java Object class, in Python (from version 3.x), object is root of all classes.
Like Java Object class, in Python (from version 3.x), object is root of all classes.
In
Python 3.x, “class Test(object)” and “class Test” are same.
In Python 2.x, “class Test(object)” creates a class with object as parent (called new style class) and “class Test” creates old style class (without object parent). Refer this for more details.
In Python 2.x, “class Test(object)” creates a class with object as parent (called new style class) and “class Test” creates old style class (without object parent). Refer this for more details.
Does
Python support Multiple Inheritance?
Unlike Java and like C++, Python supports multiple inheritance. We specify all parent classes as comma separated list in bracket.
Unlike Java and like C++, Python supports multiple inheritance. We specify all parent classes as comma separated list in bracket.
|
# Python example to show working of multiple
# inheritance
class Base1(object):
def
__init__(self):
self.str1
= "Geek1"
print "Base1"
class Base2(object):
def
__init__(self):
self.str2
= "Geek2"
print "Base2"
class Derived(Base1, Base2):
def
__init__(self):
# Calling
constructors of Base1
# and
Base2 classes
Base1.__init__(self)
Base2.__init__(self)
print "Derived"
def
printStrs(self):
print(self.str1,
self.str2)
ob = Derived()
ob.printStrs()
|
Output:
Base1
Base2
Derived
('Geek1', 'Geek2')
How
to access parent members in a subclass?
1. Using Parent class name
|
# Python example to show that base
# class members can be accessed in
# derived class using base class name
class Base(object):
# Constructor
def
__init__(self, x):
self.x = x
class Derived(Base):
# Constructor
def
__init__(self, x, y):
Base.x = x
self.y = y
def
printXY(self):
# print(self.x,
self.y) will also work
print(Base.x,
self.y)
# Driver Code
d = Derived(10,
20)
d.printXY()
|
Output:
(10, 20)
2. Using super()
We can also access parent class members using super.
We can also access parent class members using super.
|
# Python example to show that base
# class members can be accessed in
# derived class using super()
class Base(object):
# Constructor
def
__init__(self, x):
self.x = x
class Derived(Base):
# Constructor
def
__init__(self, x, y):
''' In
Python 3.x, "super().__init__(name)"
also
works'''
super(Derived,
self).__init__(x)
self.y = y
def
printXY(self):
# Note that
Base.x won't work here
# because
super() is used in constructor
print(self.x,
self.y)
# Driver Code
d = Derived(10,
20)
d.printXY()
|
Output:
(10, 20)
Note that the above two methods are
not exactly the same. In the next article on inheritance, we will covering
following topics.
1) How super works? How accessing a member through super and parent class name are different?
2) How Diamond problem is handled in Python?
1) How super works? How accessing a member through super and parent class name are different?
2) How Diamond problem is handled in Python?
Exercise:
Predict the output of following Python programs
Predict the output of following Python programs
|
class X(object):
def
__init__(self, a):
self.num = a
def
doubleup(self):
self.num
*= 2
class Y(X):
def
__init__(self, a):
X.__init__(self,
a)
def
tripleup(self):
self.num
*= 3
obj = Y(4)
print(obj.num)
obj.doubleup()
print(obj.num)
obj.tripleup()
print(obj.num)
|
Output:
4
8
24
|
# Base or Super class
class Person(object):
def
__init__(self, name):
self.name
= name
def
getName(self):
return self.name
def
isEmployee(self):
return False
# Inherited or Subclass (Note Person in bracket)
class Employee(Person):
def
__init__(self, name, eid):
''' In
Python 3.0+, "super().__init__(name)"
also
works'''
super(Employee,
self).__init__(name)
self.empID
= eid
def
isEmployee(self):
return True
def
getID(self):
return self.empID
# Driver code
emp = Employee("Geek1", "E101")
print(emp.getName(), emp.isEmployee(), emp.getID())
|
Output:
('Geek1', True, 'E101')