We introduced the concept of Object oriented programming in the last chapter. We also looked at what classes and objects are with examples.
Let’s now see how classes and objects are created and used in Python.
Python Creating Classes and Objects
A class is defined using the class
keyword.
class Square():
pass
Here, Square
is the name of a class. In other words, Square
is a class.
In the body of this class, we have not defined anything yet and so passed the keyword pass
.
Let’s make an object of this class.
class Square():
pass
sq = Square()
Here, sq
is an object of the class Square or you can also say sq
is a Square.
class Square():
pass
sq1 = Square()
sq2 = Square()
In this example, we have made two objects of the class Square - sq1
and sq2
. We can say that sq1
is a Square and sq2
is another Square.
We can define variables inside a class. These variables defined inside a class are called attributes. These variables (attributes) can be accessed by all the objects of the class.
We know that each square has a side. Thus, we can define an attribute ‘side’ inside the Square
class as shown below.
Let’s create a simple class.
# class definition
class Square():
side = 14
# creating object of class Square
sq = Square()
print(sq.side)
class Square():
→ Square
is the name of a class.
side = 14
→ The class has an attribute named side
having a value of 14.
sq = Square()
→ sq
is an object of the class Square
. This also means that sq
is a Square. A class can have any number of objects.
print(sq.side)
→ The object sq
accesses the class attribute side
and its value is printed.
In the above example, we can say that sq
is a square whose side is 14.
It’s this easy to create a class and its object.
Now let’s create two objects of the class Square
.
# class definition
class Square():
side = 14
# creating objects of class Square
sq1 = Square()
sq2 = Square()
print(sq1.side)
print(sq2.side)
We created two objects sq1
and sq2
of the class Square
. In simple English, we can say that sq1
and sq2
are two squares having sides equal to 14.
Now suppose in the above example, these two objects have sides of different length. In that case, we can change the value of the class attribute side
for each object as shown below.
# class definition
class Square():
side = 14
# creating objects of class Square
sq1 = Square()
sq2 = Square()
# changing value of side attribute for each object
sq1.side = 10
sq2.side = 20
print(sq1.side)
print(sq2.side)
sq1.side = 10
changed the value of side
for the object sq1
to 10 and sq2.side = 20
changed the value of side for the object sq2
to 20. In other words, sq1
is a square having side 10 and sq2
is a square having side 20.
Now that was cool.
We can define attributes for objects without defining those attributes in the class as shown below.
# class definition
class Rectangle():
pass
# creating objects of class Rectangle
rc1 = Rectangle()
rc2 = Rectangle()
# defining attributes for rc1 object
rc1.length = 10
rc1.breadth = 30
# defining attributes for rc2 object
rc2.breadth = 20
print(sq1.length)
print(sq1.breadth)
print(sq2.breadth)
In the above example, we didn’t define any attribute inside the class. The attributes length
and breadth
are defined for the object rc1
and an attribute breadth
is defined for the object rc2
.
Note that there is no attribute named length
for the object rc2
. Therefore, if rc2
tries to access length
through rc2.length
in the above program, then we will get an error as shown below.
# class definition
class Rectangle():
pass
# creating objects of class Rectangle
rc1 = Rectangle()
rc2 = Rectangle()
# defining attributes for rc1 object
rc1.length = 10
rc1.breadth = 30
# defining attributes for rc2 object
rc2.breadth = 20
print(rc2.length)
Now you know how to create classes and objects. So, let’s move forward and see what else we can do with classes and objects..
Python Accessing Class Attributes by Class
In the above examples, we accessed the attributes of a class through the objects of that class (for example, the object ‘sq’ accessed the attribute ‘side’ of the class ‘Square’). However, we can also access the attributes of a class by the class itself without creating any object.
Look at the following example.
# class definition
class Rectangle():
length = 10
# accessing class attribute length
print("Length:", Rectangle.length)
In this example, the class Rectangle
directly accessed its attribute length
through Rectangle.length
without creating any object.
A class can also define a new attribute outside the class definition as shown below.
# class definition
class Rectangle():
length = 10
# accessing class attribute length
print("Length:", Rectangle.length)
# defining new class attribute breadth
Rectangle.breadth = 20
print("Breadth:", Rectangle.breadth)
The class Rectangle
accessed its attribute length
and defined a new attribute breadth
outside its class definition.
Python Methods Inside Class
Like variables defined in a class are called attributes, functions defined in a class are called methods. All the objects of a class can access the variables and can call the methods defined inside the class.
# class definition
class Square():
side = 14
def description(self):
print("This is a Square")
# creating objects of class Square
sq = Square()
print(sq.side) # accessing variable side of class
sq.description() # calling method description() of class
The class Square
has two members- a variable side
and a method description()
. We created an object sq
of this class. Therefore, the object was able to access the class variable (sq.side
) and call the class method (sq.description()
).
However, you must be wondering why we passed self
as the parameter to the method description()
.
self
is a self-referencing pointer. It is necessary to pass self
as a parameter if the method is inside a class. This is because when an object calls a method, Python automatically passes the object as the first argument to the method.
So, if we do not write self
as a parameter, we will get an error. Try removing self
and see the error.
Look at another example.
# class definition
class Square():
def perimeter(self, side):
return side * 4
# object1
sq1 = Square()
print("Perimeter of Object 1:", sq1.perimeter(10))
# object2
sq2 = Square()
print("Perimeter of Object 2:", sq2.perimeter(20))
Inside the Square
class, a method named perimeter()
is defined that takes the side as input and returns the perimeter. We created two objects sq1
and sq2
of the class. The first object called the perimeter()
method passing 10 as the argument. Similarly, the second object called the method by passing 20 as the argument.
Note that when an object called the class method perimeter()
, Python automatically passed the object as the first argument. Thus, a total of two arguments were passed - instance of object and a value, which got assigned to the parameters self
and side
respectively.
Python Using self to Access Attributes
The attributes in a class can be accessed inside a method of the same class using self
.
You will understand this concept by looking at some examples.
Look at the following example.
# class definition
class Square():
def perimeter(self):
return side * 4
# object1
sq1 = Square()
sq1.side = 10
print("Perimeter of Object 1:", sq1.perimeter())
# object2
sq2 = Square()
sq2.side = 20
print("Perimeter of Object 2:", sq2.perimeter())
Whoops, this program threw an error. We got this error because in the perimeter()
method, Python is not sure that the side
in side * 4
is of which object. (sq1 has a side of 10 and sq2 has a side of 20)
We can correct this by replacing side
by self.side
as shown below.
# class definition
class Square():
def perimeter(self):
return self.side * 4
# object1
sq1 = Square()
sq1.side = 10
print("Perimeter of Object 1:", sq1.perimeter())
# object2
sq2 = Square()
sq2.side = 20
print("Perimeter of Object 2:", sq2.perimeter())
As mentioned before, self
refers to the current object. In other words, self
refers to the object which called the method.
In this example, when the object sq1
calls the method perimeter()
, then self refers to sq1
. In that case, writing self.side is the same as writing sq1.side.
Similarly, when the method is called by the object sq2
, then writing self.side
is the same as writing sq2.side
.
If you understood till here, well done! You have understood the major concepts related to classes and objects. Now let’s see what more is there.
Python Use of ‘self’
So, use of 'self' are:
- It is passed automatically as the first parameter when you call a method on an instance.
- It is used if we want to access an instance variable from the instance method, from inside that method.
Python Class Attributes and Instance Attributes
Class attributes are the variables which belong to a class and are accessible by all the objects of that class. These attributes are defined outside of all the class methods.
# class definition
class Counter():
count = 0 # count is class attribute
def increase(self):
Counter.count = Counter.count + 1
# creating object of class Counter
c1 = Counter()
c1.increase()
print(c1.count)
# creating object of class Counter
c2 = Counter()
c2.increase()
print(c2.count)
In the class Counter
, the variable count
is declared outside the class method and thus is a class attribute. The first object c1
called the method increase()
which increased the value of count
by 1 making it 1. Similarly, another object c2
called the method increase()
to increase the value of count to 2. Thus, you can see that after the value of count got changed when the object c1
called the method, the updated value of count was available for the object c2
.
Note that inside a class method, an attribute can be accessed either by the class or its objects. In this example, since the attribute is a class attribute, we accessed it with the help of the class Counter inside the method as Counter.count
.
Thus, the class attribute count
is common for all class objects.
Let’s again look at the following example which we saw in the beginning of this chapter.
# class definition
class Square():
side = 14
# creating objects of class Square
sq1 = Square()
sq2 = Square()
print(sq1.side)
print(sq2.side)
Here also, side
is a class attribute because both the objects of the class are able to access it.
Instance variables are the variables which belong to a specific object.
Let’s again take the following example.
# class definition
class Square():
def perimeter(self):
return self.side * 4
# object1
sq1 = Square()
sq1.side = 10
print("Perimeter of Object 1:", sq1.perimeter())
# object2
sq2 = Square()
sq2.side = 20
print("Perimeter of Object 2:", sq2.perimeter())
Here, side
in self.side
is an instance attribute because its value is different for each method.
Now let’s move on to the last concept of this chapter.
Python Constructor
A constructor is a special method of a class which gets called automatically when an object of that class is created. In Python, the __init__()
method is called the constructor.
A constructor is used to initialize variables when an object of that class is created.
class Student():
def __init__(self, name):
self.name = name
s = Student("Sam")
print(s.name)
__init__(self, name)
→ This is the constructor which gets called when an object of class Student
is created. It takes name
as a parameter, which means that we must pass a value while making an object of the Student
class.
self.name = name
→ This is the body of the constructor. name
in self.name
is an attribute. It implies that the Student
class will have some attribute name
. Whereas name on the right side of '=' is the parameter that we will pass to the __init__
method at the time of object creation.
s = Student("Sam")
→ We are creating an object s
of the Student
class and passing a string "Sam" while creating it. This string "Sam" is passed to the name parameter of __init__(self, name)
.
In self.name = name
, name
on the right side is the parameter in the method __init__(self, name)
and name in self.name
is an attribute of the Student
object.
You are now ready with the idea of class, objects and methods. Let's look at an example and get the concept clearer.
class Rectangle():
def __init__(self, l, b):
self.length = l
self.breadth = b
def getArea(self):
return self.length * self.breadth
def getPerimeter(self):
return 2*(self.length + self.breadth)
rect = Rectangle(2,4)
print(rect.getArea())
print(rect.getPerimeter())
Most of the program must be clear to you.
In this program, the constructor __init__()
takes two arguments whenever an object of the class Rectangle
is created. The first argument is assigned to the parameter l and the second is assigned to the parameter b
.
The statement self.length = l
specifies that length
is an attribute of the Rectangle
object and is assigned the value of the parameter l
. Similarly, the statement self.breadth = b
specifies that breadth
is also an attribute of the Rectangle
object and is assigned the value of the parameter b
. self
in these two statements refer to the Rectangle class.
In the getArea
method, the parameter self
refers to the object which calls this method. Thus, self.length
and self.breadth
refers to the length and breadth of the current object (object which calls the method). For example, when the object rect
calls this method, then self.length ('rect' is calling) will refer to the length of rect i.e. 2.
So this was all in classes and objects. If you have reached till here, that means you have just understood what many beginners struggle with.
Go to the practice section and solve questions, ask doubts. That will make a strong foundation of classes and objects.