Jupyter Snippet P4M 07
Jupyter Snippet P4M 07
All of these python notebooks are available at https://gitlab.erc.monash.edu.au/andrease/Python4Maths.git
Variables, Lists, Dictionaries etc in python are objects. Without getting into the theory part of Object Oriented Programming, explanation of the concepts will be done along this tutorial.
A class is declared as follows
class class_name: methods (functions)``` ```python class FirstClass: "This is an empty class" pass
pass in python means do nothing. The string defines the documentation of the class, accessible via
Above, a class object named “FirstClass” is declared now consider a “egclass” which has all the characteristics of “FirstClass”. So all you have to do is, equate the “egclass” to “FirstClass”. In python jargon this is called as creating an instance. “egclass” is the instance of “FirstClass”
egclass = FirstClass()
Objects (instances of a class) can hold data. A variable in an object is also called a field or an attribute. To access a field use the notation
object.field. For example:x
obj1 = FirstClass() obj2 = FirstClass() obj1.x = 5 obj2.x = 6 x = 7 print("x in object 1 =",obj1.x,"x in object 2=",obj2.x,"global x =",x)
x in object 1 = 5 x in object 2= 6 global x = 7
Now let us add some “functionality” to the class. A function inside a class is called as a “Method” of that class
class Counter: def reset(self,init=0): self.count = init def getCount(self): self.count += 1 return self.count counter = Counter() counter.reset(0) print("one =",counter.getCount(),"two =",counter.getCount(),"three =",counter.getCount())
one = 1 two = 2 three = 3
Note that the
reset() and function and the
getCount() method are callled with one less argument than they are declared with. The
self argument is set by Python to the calling object. Here
counter.reset(0) is equivalent to
Using self as the name of the first argument of a method is simply a common convention. Python allows any name to be used.
Note that here it would be better if we could initialise Counter objects immediately with a default value of
count rather than having to call
reset(). A constructor method is declared in Python with the special name
class FirstClass: def __init__(self,name,symbol): self.name = name self.symbol = symbol
Now that we have defined a function and added the __init__ method. We can create a instance of FirstClass which now accepts two arguments.
eg1 = FirstClass('one',1) eg2 = FirstClass('two',2)
print(eg1.name, eg1.symbol) print(eg2.name, eg2.symbol)
one 1 two 2
dir( ) function comes very handy in looking into what the class contains and what all method it offers
print("Contents of Counter class:",dir(Counter) ) print("Contents of counter object:", dir(counter))
Contents of Counter class: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'getCount', 'reset'] Contents of counter object: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'count', 'getCount', 'reset']
dir( ) of an instance also shows it’s defined attributes so the object has the additional ‘count’ attribute. Note that Python defines several default methods for actions like comparison (
__le__ is $\le$ operator). These and other special methods can be defined for classes to implement specific meanings for how object of that class should be compared, added, multiplied or the like.
Changing the FirstClass function a bit,
Just like global and local variables as we saw earlier, even classes have it’s own types of variables.
Class Attribute : attributes defined outside the method and is applicable to all the instances.
Instance Attribute : attributes defined inside a method and is applicable to only that method and is unique to each instance.
class FirstClass: test = 'test' def __init__(self,n,s): self.name = n self.symbol = s
Here test is a class attribute and name is a instance attribute.
eg3 = FirstClass('Three',3)
TEST Three 3
There might be cases where a new class would have all the previous characteristics of an already defined class. So the new class can “inherit” the previous class and add it’s own methods to it. This is called as inheritance.
Consider class SoftwareEngineer which has a method salary.
class SoftwareEngineer: def __init__(self,name,age): self.name = name self.age = age def salary(self, value): self.money = value print(self.name,"earns",self.money)
a = SoftwareEngineer('Kartik',26)
Kartik earns 40000
[ name for name in dir(SoftwareEngineer) if not name.startswith("_")]
Now consider another class Artist which tells us about the amount of money an artist earns and his artform.
class Artist: def __init__(self,name,age): self.name = name self.age = age def money(self,value): self.money = value print(self.name,"earns",self.money) def artform(self, job): self.job = job print(self.name,"is a", self.job)
b = Artist('Nitin',20)
Nitin earns 50000 Nitin is a Musician
[ name for name in dir(b) if not name.startswith("_")]
['age', 'artform', 'job', 'money', 'name']
money method and salary method are the same. So we can generalize the method to salary and inherit the SoftwareEngineer class to Artist class. Now the artist class becomes,
class Artist(SoftwareEngineer): def artform(self, job): self.job = job print self.name,"is a", self.job
c = Artist('Nishanth',21)
['__doc__', '__init__', '__module__', 'artform', 'salary']
Nishanth earns 60000 Nishanth is a Dancer
Suppose say while inheriting a particular method is not suitable for the new class. One can override this method by defining again that method with the same name inside the new class.
class Artist(SoftwareEngineer): def artform(self, job): self.job = job print(self.name,"is a", self.job) def salary(self, value): self.money = value print(self.name,"earns",self.money) print("I am overriding the SoftwareEngineer class's salary method")
c = Artist('Nishanth',21)
Nishanth earns 60000 I am overriding the SoftwareEngineer class's salary method Nishanth is a Dancer
If the number of input arguments varies from instance to instance asterisk can be used as shown.
class NotSure: def __init__(self, *args): self.data = ' '.join(list(args))
yz = NotSure('I', 'Do' , 'Not', 'Know', 'What', 'To','Type')
'I Do Not Know What To Type'
We have already seen the
dir() function for working out what is in a class. Python has many facilities to make introspection easy (that is working out what is in a Python object or module). Some useful functions are hasattr, getattr, and setattr:
ns = NotSure('test') if hasattr(ns,'data'): # check if ns.data exists setattr(ns,'copy', # set ns.copy getattr(ns,'data')) # get ns.data print('ns.copy =',ns.copy)
ns.copy = test