Difference between Python classmethod and staticmethod

Posted in /  

Difference between Python classmethod and staticmethod
vinaykhatri

Vinay Khatri
Last updated on November 21, 2024

    In Python class, we can define three types of functions/methods- regular method(self), classmethod(cls), and staticmethod. Among these three methods, you will be using the regular methods for most of the cases because classmethod and staticmethod have their specific usages and are not often used in the class body.

    Although this article is about the difference between Python class classmethod and staticmethod but for a quick reference, we will discuss the regular method first for a better understanding of classmethod and staticmethod .

    Difference between Python classmethod and staticmethod

    Python regular Method with self

    Methods are nothing but functions defined inside the class body, and to define a regular method in a Python class we pass a conventional self argument to every method. Where the self represents the instance of the class that calls that method.

    For example

    class Student:
        def __init__(self, name):
            self.name = name
    
        def show_name(self):
            return self.name
    
    r = Student("Ravi")
    print(r.show_name())   #Ravi

    In this example the r is the one instance/object of class Student() , similarly, a class can have multiple instances. When the r call the class method show_name(self) using the r.show_name() statement, it does not require passing the self parameter, because it gets automatically filled by the interpreter, as the object which is calling the method.

    In our case r is calling the show_name(self) method, so at the backend, the interpreter will treat the r instance as the self parameter and show the result accordingly. This is how a regular method work in Python class, in which an instance or object is automatically passed as the first parameter of the method as self .

    Now let's see another example of the class regular method (self).

    class Student4Grade:
        
        fee = 2300
        
        def __init__(self, fname, lname, age):
            self.fname = fname
            self.lname= lname
            self.age = age
    
        def fullname(self):
            return self.fname + " "+ self.lname
    
        def fee_increment(self):
            self.fee += 200
    
        def show_fee(self):
            return f"{self.fname} fee is: {self.fee}"
    
    
    rahul =  Student4Grade("Rahul", "Singh", 10)
    ravi   = Student4Grade("Ravi", "kumar", 9)
    
    print(ravi.fullname())
    print(rahul.fullname())
    
    rahul.fee_increment()
    
    print(ravi.show_fee())
    print(rahul.show_fee())

    Output

    Ravi kumar
    Rahul Singh
    Ravi fee is: 2300
    Rahul fee is: 2500

    Behind the code

    In this example, we created two instances/objects of class Student4Grade( ) rahul and ravi . And using the rahul.fee_increment() statement we increased the fee for rahul only, becaue when the rahul.fee_increment() statement gets executed, it passed only rahul instance to the fee_increment(self) method, not the ravi instance.

    The fee structure should remain the same for all the similar grade students, but with the self or regular method, we can only change a constant thing for a specific object using a single statement. You can say we can also call the fee_increment() method using the ravi object it will increase the fee for ravi too, that's one of the cases.

    This will do the trick but let's say if we have thousands of student objects, then it would not be a feasible solution. Some could also say to change the fee property using a class name outside the class and change it for every instance, this will also do the trick, but it violates the encapsulation and data hiding property of the class. To tackle such problems where we want to create a method that will access or change the class property for all the instances, there we can use the @calssmethod.

    Python @classmethod with cls

    @classmethod is a Python decorator . It is used to bind the specific class method to the class instead of an object, unlike regular class methods. In a regular method, we pass self as the first argument to the method, similarly in @classmethod we pass cls as the first argument to the method.

    Like self the word cls is a conventional name. You can use any arbitrary name instead of cls , but it recommends following the convention and use cls . As self represent the object the cls represent the class itself.

    Syntax

    class class_name:
        @classmethod
        def method_name(cls):
          .....

    Now let's solve the problem that we been facing in the above example

    class Student4Grade:
        
        fee = 2300
        
        def __init__(self, fname, lname, age):
            self.fname = fname
            self.lname= lname
            self.age = age
    
        def fullname(self):
            return self.fname + " "+ self.lname
    
        @classmethod
        def fee_increment(cls):    #cls is Student4Grade
            cls.fee += 200     # equivalent to Student4Grade.fee 
    
        def show_fee(self):
            return f"{self.fname} fee is: {self.fee}"
    
    
    rahul =  Student4Grade("Rahul", "Singh", 10)
    ravi   = Student4Grade("Ravi", "kumar", 9)
    
    print(ravi.fullname())
    print(rahul.fullname())
    
    Student4Grade.fee_increment()   #call fee_increment() using class
    
    print(ravi.show_fee())
    print(rahul.show_fee())

    Output

    Ravi kumar
    Rahul Singh
    Ravi fee is: 2500
    Rahul fee is: 2500

    Behind the code

    In the above example, we defined the @classmethod fee_increment(cls) , here the cls represent the class itself, not the object. So when we call the Student4Grade.fee_increment() statement it invoked the fee_increment(cls) method and it set the fee to cls.fee += 200 . And the fee change can be seen in every class object ravi and rahul .

    Python @staticmethod Methods

    Sometimes we define a method inside a function that does not use class and object property. In that case, we use static methods. Similar to the @classmethod @staticmthod is also a decorator and unlike regular methods and @classmethod it neither binds the method with object nor with class.

    It can be treated as a simple function inside the class that does not use self or cls property. As it does not bind the method with object and class, this means we can not use any class property or method inside it.

    Example

    class Student4Grade:
        
        fee = 2300
        
        def __init__(self, fname, lname, age):
            self.fname = fname
            self.lname= lname
            self.age = age
    
        def fullname(self):
            return self.fname + " "+ self.lname
    
        @classmethod
        def fee_increment(cls):    #cls is Student4Grade
            cls.fee += 200     # equivalent to Student4Grade.fee 
    
        def show_fee(self):
            return f"{self.fname} fee is: {self.fee}"
    
        @staticmethod
        def is_student():
            return True
    
    
    rahul =  Student4Grade("Rahul", "Singh", 10)
    ravi   = Student4Grade("Ravi", "kumar", 9)
    
    print(ravi.is_student())    #True
    print(rahul.is_student())  #True

    Behind the code

    In the above example the @staticmethod is_student() can be called using object ravi and rahul , but it can not use their properties and methods. Because when the is_student() function is invoked, the interpreter does not know which object is calling it.

    Head to Head comparison

    Regular Method (self) @classmethod (cls) @staticmethod()
    Normal methods inside the class decorator methods decorator methods
    Bind the method with a specific object. Bind the method with the complete class. Do not bind the method with object and class.
    method first argument must be self method first argument must be cls Does not require an argument.

    Summary

    • Normal methods are used to bind the method with an object where self represent the object/instance itself.
    • Class Method is created using @classmethod decorator, and it binds the method to the class itself using cls argument.
    • Static Method is created using @staticmethod decorator, and it does not bind the method with class or object.

    People are also reading:

    Leave a Comment on this Post

    0 Comments