DEV Community

Main
Main

Posted on • Originally published at pynerds.com

Instance, Class and Static methods in Python

Methods are functions that are associated with a particular object or class. The three types of methods are :

  1. Instance methods: These methods are associated with instances of a class and can access and modify the data within an instance.
  2. Class methods: These methods are associated with a class rather than instances.  They are used to create or modify class-level properties or behaviors.
  3. Static methods: These are utility methods that do not have access to any object-level or class-level data.

Understanding the difference between the 3 types of  methods will be crucial in ensuring that you write classes that  are properly organized, efficient, easy to maintain and which are a close reflection of the real life objects they are being modeled after. 

The following  example shows how each of these methods are defined in a class. We will talk about the technical details in a while.

class Example:
    #define an instance method
    def method(self):
        Return "I am an instance method"
    
    #define a class method
    @classmethod
    def class_method(cls):
        return "I am a class method"
    
    #Define a static method
    @staticmethod
    def static_method():
        return "I am a static method"

Instance Methods

Instance methods are functions defined inside a class that perform operations on instances rather than the class itself.

If you have interacted with Python classes, it is likely that you have encountered and used instance methods. You can easily identify the methods by looking for the  parameter self in the method definition.

#define the class
class Example:
    #Define an instance method
    def method(self):
        return "I am an instance method. I will only work when called by objects of this class!"

#create an object
e = Example()
#call an instance method
print(e.method())

Instance methods are able to access and modify an instance variables and data. 

class Student:

   #Define the constructor
   def __init__(self, name, grade):
       self.name = name  
       self.grade = grade

   #define other instance methods
   def change_grade(self, new_grade):
       self.grade = new_grade 

   def print_info(self):
       print(f"{self.name} is in grade {self.grade}") 

s1 = Student("Bob", 9)

s1.print_info() 

s1.change_grade(10)

s1.print_info()

 Note: Calling an instance method from the class itself will raise a TypeError.

#define the class
class Example:

    #Define an instance method
    def method(self):
        return "I am an instance method. I will only work when called by objects!"

#Try calling an instance method from the class itself. An error is raised!.
print(Example.method())

Instance methods cannot modify class level variables

Instance methods are only able to access and modify instance variables, which exist only within the scope of an instance of a class. As such, they cannot access or modify class level variables.

class Example:
   #Define a class level variable
   x = 10

   #The following method will modify the value of x at instance level rather than at class level
   def modify(self):
      self.x = 1000


print(Example.x)

e = Example()
e.modify()
print(Example.x)

Class Methods

Class methods are methods that are bound to a class rather than to objects. These methods can be called directly from the class itself as well as from the instances. 

Class methods take cls as the first argument. The cls argument is a reference to the class, and is used to access class attributes and methods. It is analogous to the self argument for instance methods.

We use the @classmethod decorator to define a class method. The syntax is as follows:

@classmethod
def method_name(cls):
    #method body

Class methods  operate on the class itself, rather than on an instances of the class. They are used to provide general functionality for objects of that particular class.

Consider the following example:

class Example:
   #Define a class level variable
   x = 10

   #The following method will modify the value at class level
   @classmethod
   def modify(cls, v):
      """Modify the value of the class level variable x with the new variable v"""
      cls.x = v


print(Example.x)

#Call class method from the class itself
Example.modify(100)
print(Example.x)

#call class method from an instance
e = Example()
e.modify(1000)
print(Example.x)

The following example shows how we can keep a count of all the active instances of a class using class method.

#Define the class
class Example:
   
   #The variable to keep the count
   count = 0

   def __init__(self):
      self.increase_count() #Call increas count each time a new object is created.
   
   @classmethod
   def increase_count(cls):
       """This method increases the global level variable, 'count' """
       cls.count +=1
  
   @classmethod
   def get_count(cls):
       return cls.count

#The following exampls demonstrate the methods at work.

print(Example.get_count())

e1 = Example()
print(Example.get_count())

e2 = Example()
e3 = Example()
print(Example.get_count())

e4 = Example()
e5 = Example()
print(e5.get_count())
   

Static methods

From the above discussions, instance methods operate on instances, while class method operate on the class itself.

Static methods,  as the name suggests are just static. They belong to a class but the do not have access to class or instance variables. They are simply meant for providing utility services that are not class or instance specific.

Note: While instance method  and class methods always take self,  cls as their first arguments respectively. Static methods do not take any mandatory argument as the first argument. This is because they are not bound to either the class or instances and are simply called directly.

Static methods are defined using the @staticmethod decorator.  The syntax is as follows:

@staticmethod
def method_name(params):
   #method body
class Example:

   @staticmethod
   def method():
      print("I am a static method.")

Example.method()

e = Example()
e.method()

As shown above, static methods can be called from the class itself as well as from the instances.

Consider if we have the class Rectangle, we can define a utility/static methods for calculating the area and the perimeter.

#define the class

class Rectangle:
   
   def __init__(self, w, l):
       self.width = w
       self.length = l

   #define some instance methods
   def area(self):
       """This method will call the static method 'calculate_area' """
       return self.calculate_area(self.width, self.length)

   def perimeter(self):
      """This method will call the static method 'calculate_perimeter' """
      return self.calculate_perimeter(self.width, self.length)

   #Define utilty methods that are accessible from the class as well as instances
   @staticmethod
   def calculate_area(w, l):
       return w * l

   @staticmethod
   def calculate_perimeter(w, l):
       return 2 * ( w + l)

#Use utility methods from the class
print(Rectangle.calculate_area(7, 4))
print(Rectangle.calculate_perimeter(7, 4))

#from instances
r = Rectangle(20, 30)
print(r.area())
print(r.perimeter())

r2 = Rectangle(100, 50)
print(r2.area())
print(r2.perimeter())

Summary

  1. Instance methods operate at instance level. They take self as their first argument
  2. Class methods operate at class level, they have access to class variables. They are defined using the @classmethod decorator.  They take cls as the first argument.
  3. Static methods are utility methods, they do not have access to class or instance variables. They are defined using the @staticmethod decorator and they do not take any mandatory first argument. 

Related articles


Top comments (0)