avatarSamer Sallam

Summary

This article discusses instance attributes and instance methods in Python, focusing on how they are defined and used within classes.

Abstract

In Python, instance attributes and instance methods are essential components of object-oriented programming. Instance attributes are properties that belong to individual instances of a class, while instance methods are functions that can process these attributes. The article explains how to define instance attributes using the constructor method __init__ and how to access them using the self keyword. It also covers the syntax for defining instance methods and demonstrates how to call them using objects or the class name. Additionally, the article touches on the __dict__ attribute and the vars() function, which provide dictionary representations of objects.

Bullet points

  • Instance attributes are properties that belong to individual instances of a class.
  • Instance methods are functions that can process instance attributes.
  • Instance attributes are defined using the constructor method __init__.
  • The self keyword is used to access instance attributes within a class.
  • Instance methods are defined using the def keyword and can be called using objects or the class name.
  • The __dict__ attribute provides a dictionary representation of an object.
  • The vars() function returns a dictionary representation of an object's attributes and their values.

Instance Attributes and Instance Methods: Python OOP Complete Course — Part 4

Photo by Christina Morillo on Pexles

Before we start let me tell you that:

  • This article is a part of The Complete Course in Object Oriented Programming in Python which you can find it here.
  • All resources are available in the “Resources” section below.
  • This article is also available as a YouTube video Part 1- Part 2- Part 3- Part 4.

Introduction

So far, you have defined your first class, and this is a great job! Now let us add some properties and methods to our class. So…

This article will cover the following outlines:

  1. Attributes and Methods
  2. Attributes Types and Methods Types
  3. Instance Attributes
  4. Instance Attributes Syntax
  5. Instance Methods
  6. Instance Methods Syntax

1. Attributes and Methods

Photo by NicoElNino on Unsplash

As a reminder, we have defined a class before as a prototype in which it has attributes and methods. ( If you like to remember the class definition from the previous article, just click here).

Attributes are just the properties that specify the information associated with each class object. So, If we get back to our Bank Account example, we call the “account holder name”, “account id”, and “balance” attributes. Refer to Figure 1.

Figure 1: Bank Account (Image By Author).

Usually, when we define a type, we don’t want only properties, but we also need to handle and process these properties. Therefore, we add methods. So, methods are just the functions that can process the object's attributes. In our bank account example, I call “withdraw” and “deposit” methods. Refer to Figure 2.

Figure 2: Bank Account Methods (Image By Author)

Note: each object of a class is also called a class instance.

Now, let us talk in more detail and see what are the available types of attributes and methods in Python.

2. Attributes Types and Methods Types

Photo by Philipp Katzenberger on Unsplash

For attributes, we have two types:

  • Instance Attributes
  • Class Attribute

Whereas, we have three types of methods:

  • Instance Methods
  • Class Methods
  • Static Methods

If these terms seem strange to you, do not worry they will be explained in detail in future articles.

Next in this article, we will learn about the first type of attributes and methods which is the “instance” type.

3. Instance Attributes

Instance attributes are the attributes that belong to the class instances, not to the class itself. In other words, each class instance (object) has its values for these attributes. In our Bank Account example, one of the instance attributes is “account_holder_name”. This means that each object of this bank account class should have a different name from the other objects.

For example, “John Smith” for the first object, “John doe” for the second object…so on. Refer to Figure 3.

(If you like to remember the full example from the “Introduction to Classes and Objects” article, just click here).

Figure 3: Bank account class and object (Image By Author).

The question now, is how we can add instance attributes to our class?

4. Instance Attributes Syntax

To add instance attributes to our class, first of all, we create the class itself and give it a name ClassName.

Next, we add some instance attributes which are usually defined inside a method called the constructor method. This method is defined using the keyword def like any function in Python, and this method name should be __init__. The first parameter for this method should be (self) which is a reference to the object itself (more about self will be presented later on).

Then we can list all of our instance attributes using the dot operator.

class ClassName:
def __init__(self):
        self.instance_atrr1 = None
        self.instance_atrr2 = None
new_object = ClassName()

In the previous code snippet, we have two instance attributes: instance_atrr1, and instance_atrr2 and their initial value is None.

In the last line, we are creating an object from the class. This is done by writing the class name and then () like if I am calling function. What happens beyond the scene is that the constructor method is auto-called and the object is auto-passed to this method with the name “self”. Inside the constructor, the two attributes will be attached to the object with their initial value.

In the previous example, all the instances from our class ClassName will have the same values for their instance attributes. The question now: what if I want to assign different attributes values for different objects? To solve this issue:

  • First of all, remember that: the constructor method is auto-called when we define a new object.
  • Great, so let us edit our constructor method to accept some input parameters and let us assign the passed arguments to these instance attributes.
class ClassName:
def __init__(self, value1, value2):
    self.instance_atrr1 = value1
    self.instance_atrr2 = value2
new_object = ClassName(value1, value2)

It is clear from the previous code snippet that each instance of our class ClassName will have its values for the instance attributes. These values are passed to the object from outside the class scope.

Briefly, when we define a new object what happened behind the scene is that the interpreter will automatically call the constructor method __init__ and pass the object that we are defining into this method. self will be a reference for that object and using the dot operator the instance attributes are attached to the object itself.

Photo by Brett Jordan on Unsplash

Now, let us take a real-world example to practice what we have learned.

  1. Define a new class its name, Student.
  2. Define the constructor method, print any sentence inside it, and then print the type of self parameter.
  3. Define a new object for your Student class.

Solution Input:

class Student:
def __init__(self):
    print('Hi I am a new object')
    print(type(self))
new_student = Student()

Output:

Hi I am a new object
<class '__main__.Student'>

Note:

When we print the type of “self”, we find that its type is “Student” and we can understand from this that the self is an object from the class Student.

Now, let us upgrade our class by adding:

  • Some instance attributes and give them initial values:
  1. id, age = None
  2. first_name and last_name = ‘ ’ (an empty string )
  3. full_name = first_name + last_name
  4. classes = [] an empty list.
  • Print your object id.

Some hints to help you:

  • All attributes should start with self.attribute_name while you define them.
  • When you want to access any of the instance attributes inside your class you should use self.attribute_name.
  • To access your object instance attribute out of the class scope use object_name.instance_attribute name.

Solution Input:

class Student:
    
    def __init__(self):
        self.id = None
        self.first_name = ''
        self.last_name = ''
        self.full_name = self.first_name + " " + self.last_name
        self.age = None
        self.classes = []
new_student = Student()
print(new_student.id)

Output:

None

If we try to print attribute id2:

print(new_student.id2)

We will get an error because the ‘Student’ object has no attribute ‘id2’.

Now let us give the user the flexibility to pass the values that he wants when he creates an object from the Student class.

Let us pass some arguments to the __init__ method:

Solution Input:

class Student:
    
     def __init__(self, _id, first_name, last_name, age):
        self.id = _id
        self.first_name = first_name
        self.last_name = last_name
        self.full_name = self.first_name + " " + self.last_name
        self.age = age
        self.classes = []

If we define our object as follows:

new_student = Student()
print(new_student.id)

We will get:

TypeError: __init__() missing 4 required positional arguments: '_id', 'first_name', 'last_name', and 'age'

To solve the error: We have to pass some initial values to the attributes that the __init__ method is expected to receive from our side when we define a new object so.

Solution Input:

new_student = Student(1, 'Jack', 'Ma', 25)
print(new_student.id)
print(new_student.full_name)
print(new_student.age)

Output:

1
Jack Ma
25

In conclusion, if you want to give the user the ability to specify the initial values of the attribute out of the class, you have to add some parameters to the “__init__” method according to your use case.

Now let us move on to learn about instance methods…

5. Instance Methods

Simply, instance methods are the methods that have access to the instance attributes. We define them as any normal function in Python using the keyword def, and usually, the first parameter of the instance method is always “self ” which represents the instance, object, that calls this method.

From this point, we can understand that the instance method should have access to the instance attributes to be able to handle and process these attributes.

Next, the Syntax of these methods will be explained.

Photo by Towfiqu barbhuiya on Unsplash

6. Instance Methods Syntax

To add instance methods to our class, follow these steps:

  • Define your class.
  • As usual, the first method after the class name would be the constructor method “__init__” which we use to give values to the instance attributes.
  • After that, add the instance methods one by one as normal functions, using the keyword def, then give your method a name, and between brackets pass all the function’s parameters. In the case of instance methods, the first parameter should be self.

Note:

  • You can pass any type of arguments you want to this method (positional arguments or arbitrary arguments).
  • Do not forget the colon after the brackets. Otherwise, you will get a syntax error.

Once you have defined your method, you can add the actual implementation of this method by writing some code that has access to self that in turn has access to instance attributes, as follows:

class ClassName:
      def __init__(self, value1, value2):
          self.instance_atrr1 = value1
          self.instance_atrr2 = value2
      def instance_method1(self, arg1,.., argn, *args, **kwargs):
        # do something related to instance attributes
     def instance_method2(self, arg1,.., argn, *args, **kwargs):
        # do something related to instance attributes

To complete the full picture of instance methods, let us take a real example and let us update our Student class.

class Student:
    
     def __init__(self, _id, first_name, last_name, age):
        self.id = None
        self.first_name = first_name
        self.last_name = last_name
        self.full_name = self.first_name + " " + self.last_name
        self.age = age
        self.classes = []
Photo by Christina Morillo on Pexles

Let us assume that our students' objects should be able to enrol in some university classes and to achieve this let us define an instance method called enrol which will accept the subject_name as an argument. Let us also print the full student name within this method.

Solution input:

class Student:
    
     def __init__(self, _id, first_name, last_name, age):
        self.id = None
        self.first_name = first_name
        self.last_name = last_name
        self.full_name = self.first_name + " " + self.last_name
        self.age = age
        self.classes = []
     def enrol(self, subject_name):
         print(self.full_name)
         self.classes.append(class_name)

Defining new objects:

new_student1 = Student(1, 'Jack', 'Ma', 25)
new_student2 = Student(1, 'John', 'Doe', 25)

Good, till now we have just defined our class and its instance attributes and method. Also, we have defined two new objects from that class.

But we have not called that instance method yet, because as we know from functions in the Python article (the link will be added once it is published), to use the function you should call it, then how can call the instance methods? Let us see together by assuming that the object new_student1 wants to enrol in ‘Physics’.

Some hints to help you:

You can call the instance method in two different ways:

  1. By using the object_name.the method_name(the required parameters).

Solution input:

print('Before : ', new_student1.classes)
new_student1.enrol('Physics')
print('After : ', new_student1.classes)

Output:

Before :  []
Jack Ma
After :  ['Physics']

As we see, before calling the method, we got an empty list because when we create an object, the list is empty. After that, when I use enrol method, enrol takes the class that the student enrolled in and it will append the class name to the classes list.

2. We can also call the instance method by using the ClassName itself, and then you have to specify explicitly the object that you want to call the method for because in this case the object will not be passed automatically. ClassName.method_name(object_name, the required parameters)

Solution input:

Student.enrol(new_student1, 'Math')
print('After : ', new_student1.classes)
print()

Output:

Jack Ma
After :  ['Physics', 'Math']

The last important point that should be mentioned is that methods overloading is not supported in python (in method overloading we can define multiple methods with the same name, but with a different list of parameters).

Photo by Joshua Hoehne on Unsplash

Before I end this article, let me share with you some useful ideas.

First one, in Python, for each object you create, automatically there is a __dict__ attribute will be created. To understand this attribute, you can print it. For example, let us see its value for the new_student1 object.

Solution input:

new_student1.__dict__

Output:

{'id': 1,
'first_name': 'Jack',
'last_name': 'Ma',
'full_name': 'Jack Ma',
'age': 25,
'classes': ['Physics', 'Math']}

As you see, you will get a dictionary that has keys equal to the instance attributes that we have, and values equal to the values that this object has. So, “__dict__” will give you a dictionary representative for your object, it is very useful in an application where you need to serialize your object.

For example, if you want to send the object over a network or convert it into a JSON object.

The next idea that I want to talk about is the vars() function.

Photo by Jorge Jesus on Pexles

vars() function will take an object from your class as a parameter, and it will return to you a dictionary that has keys equal to the attributes' names, and values equal to the object attributes values themselves. Let us call it our new_student1.

Solution input:

vars(new_student1)

Output:

{'id': 1,
'first_name': 'Jack',
'last_name': 'Ma',
'full_name': 'Jack Ma',
'age': 25,
'classes': ['Physics', 'Math']}

It is clear that vars() function return the value of __dict__ attribute.

Now, let us summarize what we have learned in this article:

Photo by Ann H on pexels
  • Instance Attributes are the attributes that belong to the class instances NOT the class itself.
  • Instance Methods are the methods that have access to the instance attributes to handle and process them.
  • We add instance attributes usually by defining the constructor method “__init__”.
  • Within __init__ we pass the first parameters self which represents an object from a class that is currently being defined, and usually, we attach instance attributes to these objects using the dot operator.
  • Once we define the instance attributes, we can define instance methods, which are like normal functions in Python. We use the def keyword to define them. Refer to Figure 4.
Figure 4: Instance attributes and instance methods summary (Image By Author).

P.S.: A million thanks for your time reading my story. Before you leave let me mention quickly two points:

  • First, to get my posts in your inbox directly, would you please subscribe here, and you can follow me here.
  • Second, writers made thousands of $$ on Medium. To get unlimited access to Medium stories and start earning, sign up now for Medium membership which only costs $5 per month. By signing up with this link, you can directly support me at no extra cost to you.

To get back to the previous article, you can use the following link:

Part 3:Introduction to Classes and Objects

To move on to the next article, you can use the following link:

Part 5:Class Attributes and Class Methods

Resources:

Object Oriented
Python
Programming
Instance Method
Instance Attribute
Recommended from ReadMedium