In Object Oriented Programming, everything is an object. Objects are real world entities having some attributes and some related methods that operate on attributes. We assume that the reader has some familiarity with Object Oriented Concepts such as Inheritance, Polymorphism, Abstraction and so on ...
Syntax:
class ClassName:
<statement 1>
<statement 2>
....
....
<statement n>
Unlike C++
and Java
classes, class methods does not hold the reference of current object (this
object). Class methods should take the class object as their first argument. This is not required for static methods. At the point of invocation of object methods, the object is passed to method implicitly. It is a covention to name the first parameter of class method as self
. Now let's see some special functions of classes.
__init__(self,elements)
: Constructor, called when object is created. All properties of the object have to be declared here.
__del__(self)
: Destructor, called when del
is applied to an object.
__str__(self)
: Returns the string representation of object. Called when str()
is called on the object.
__iter__(self)
: Returns the iterator of elements of the object. Called when iter()
is called on the object. Also this enables us to use the for ele in object
like construct.
__len(self)__
: Returns the length of the collection. Called when len()
is invoked on the object.__getitem(self,item)__
: Allows us to use object[item]
like accessor to get an itemAny member declared inside the class, but not in the methods, are shared by all instances of classes. A method annotated with @staticmethod
is static method, and doesn't recieve class object as it's first parameter.
private
membersA member or method whose name starts with '__
' is regarded as a private member or method.
Student
Here we implement a simple Student
class.
In [86]:
class Student:
count = 0 # Total number of objects created so far, it is static variable as it is declared outside
def __init__(self,name,usn,marks):
"""
Constructor of class Student
Input: name - name of the student : string
usn - university serial number : string
marks - marks in 3 subjects out of 20
"""
Student.count += 1
self.name = name
self.usn = usn
self.marks = marks[:] # Copy marks to self.marks .. a simple self.marks = marks make only reference equal
def print_details(self):
print(str(self))
def total_marks(self):
return sum(self.marks)
def __iter__(self):
details = {'name':self.name,'usn':self.usn,'marks':self.marks}
for k,v in details.items():
yield k,v # A tuple
def __str__(self):
return "Name : {0} \nUSN = {1}\nMarks in 3 subjects = {2}".format(self.name,self.usn,self.marks)
@staticmethod
def get_total_count():
return Student.count
In [87]:
s1 = Student('Ramesh','4jc11cs111',[20,16,18])
s2 = Student('Ravi','4jc15cs112',[15,18,18])
In [88]:
print(s1) # calls __str__()
In [89]:
print(s2)
In [91]:
Student.count
Out[91]:
In [90]:
Student.get_total_count()
Out[90]:
In [92]:
for k,v in s1:
print('{} = {}'.format(k,v))
In [95]:
s1.print_details() # self of Student.print_details(self) is passed as s1
In [97]:
Student.print_details(s1) # Explicitly passing self parameter
In [98]:
Student.get_total_count()
Out[98]:
In [100]:
s1.get_total_count() # This is also possible, @staticmethod attribute prevents passing object to method
Out[100]:
In C
, C++
, Java
and C#
, we have to predefine the data type of every variable declared. In Python, you may have observed that you are not defining any data type during variable declaration. In fact, Python does not require you to do that.
In C
,
int x;
means storage space allocated to x
is constant 8 bytes (on x64
system) and this space will never change. This also implies that x
will never hold other values than int. Trying to do so will raise a compiler error. This nature of C
makes the language statically typed
, i.e., data type of a variable is determined at the compile time.
On the other hand, in Python, the type of variable is determined entirely during runtime. Storage space allocated to a variable can vary dynamically. When we assign a string to a variable x
, it will be str
. If we reassign it to a list, it will be list
. This nature of Python
makes it dynamically typed
language. It is also called as Duck typing
.
Duck typing is an application of the duck test in type safety. It requires that type checking be deferred to runtime, and is implemented by means of dynamic typing or reflection.
The Duck test is a humorous term for a form of abductive reasoning. This is its usual expression:
If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.
The duck test can be seen in the following example. As far as the function in_the_forest
is concerned, the Person object is a duck:
In [1]:
class Duck:
def quack(self):
print("Quaaaaaack!")
def feathers(self):
print("The duck has white and gray feathers.")
class Person:
def quack(self):
print("The person imitates a duck.")
def feathers(self):
print("The person takes a feather from the ground and shows it.")
def name(self):
print("John Smith")
def in_the_forest(duck):
duck.quack()
duck.feathers()
def game():
donald = Duck()
john = Person()
in_the_forest(donald)
in_the_forest(john)
game()
In [102]:
x = 8
type(x)
Out[102]:
In [103]:
type(8.5)
Out[103]:
In [104]:
type('hello')
Out[104]:
In [105]:
type([1,2,1])
Out[105]:
In [106]:
type({})
Out[106]:
In [108]:
type((1,))
Out[108]:
In [109]:
type(s1)
Out[109]:
In [111]:
import random
type(random)
Out[111]:
The main intention of interfaces in Java
and C#
was to make the classes to have a set of common functions, which makes their usage alike. Due to Duck Typing, the need for interfaces is now gone