Close
Close

Python Classes and Objects


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)
Output
14

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.

Class and object in Python

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.

In Python, the terms object and instance are used interchangeably, and the creation of an object is also called instantiation.

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)
Output
14
14

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)
Output
10
20

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)
Output
10
30
20

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)
Output
Traceback (most recent call last):
  File "script.py", line 16, in <module>
    print(rc2.length)
AttributeError: Rectangle object has no attribute '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)
Output
Length: 10

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)
Output
Length: 10
Breadth: 20

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
Output
14
This is a Square

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.

self pointer in Python

So, if we do not write self as a parameter, we will get an error. Try removing self and see the error.

self pointer in Python

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))
Output
Perimeter of Object 1: 40
Perimeter of Object 2: 80

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.

self parameter in Python

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())
Output
Traceback (most recent call last):
  File "script.py", line 9, in <module>
    print("Perimeter of Object 1:", sq1.perimeter())
  File "script.py", line 4, in perimeter
    return side * 4
NameError: name 'side' is not defined

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())
Output
Perimeter of Object 1: 40
Perimeter of Object 2: 80

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)
Output
1
2

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)
Output
14
14

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())
Output
Perimeter of Object 1: 40
Perimeter of Object 2: 80

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)
Output
Sam

__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())
Output
8
12

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.

To learn from simple videos, you can always look at our Python video course on CodesDope Pro. It has over 500 practice questions and over 20 projects.
The way to get started is to quit talking and begin doing.
- Walt Disney


Ask Yours
Post Yours
Doubt? Ask question