Support Our Site

To ensure we can continue delivering content and maintaining a free platform for all users, we kindly request that you disable your adblocker. Your contribution greatly supports our site's growth and development.

Python's @classmethod and @staticmethod Explained

3 min read

For beginners who are learning object-oriented programming in Python, it is very essential to have a good grasp over class method and static method for writing more optimized and reusable code.

Also, it is very common for even experienced programmers coming from different languages to get confused between these two.

In this article, we will develop a better understanding of the class method and static methods in Python.

Static Method in Python

A @staticmethod is a method that knows nothing about the class or instance it was called on unless explicitly given. It just gets the arguments that were passed, no implicit first argument and It’s definition is immutable via inheritance.

In simpler words a @staticmethod  is nothing more than a regular function defined inside a class that doesn't have access to the instance therefore It is callable without instantiating the class.

Syntax:

class ClassName:
    @staticmethod
    def method_name(arg1, arg2, ...):
 ...

We use the @staticmethod decorator for defining a static method in Python, here you can observe that the static method is not taking self as an argument for the method.

Now let's look at an example.

class Myclass():
    @staticmethod
    def staticmethod():
        print('static method called')

As we discussed we can access the static method of a class without creating an object.

Myclass.staticmethod()

Output:

static method called

Although calling the method from a class instance is also possible.

my_obj = Myclass()
my_obj.staticmethod()

Output:

static method called

Great, but when are static methods useful?

The static method helps in achieving encapsulation in Python class since it is not aware of the state of the current instance. Also, static methods make code more readable and reusable and more convenient to import versus module-level functions since each method does not have to be specially imported.

class Person():
    @staticmethod
    def is_adult(age):
        if age > 18:
            return True
        else:
            return False

In the above example, we can check if the person is an adult with or without initiating the class.

Person.is_adult(23)

Output:

True

Class Method in Python

A @classmethod is a method that receives the class as the implicit first argument, just like an instance method receives the instance. This means you can use the class and its properties inside that method rather than a particular instance.

So @classmethod is basically a method of a class having access to every attribute of the class it was called on. Therefore a class method is a method that is bound to the class and not the object of the class.

Syntax:

class Class:
    @classmethod 
   def method(cls, arg1, arg2, ...):
 ... 

The @classmethod decorator is used for creating a class methods and cls should be the first argument of every class method.

class MyClass:
    @classmethod
    def classmethod(cls):
        print('Class method called')

@classmethod functions are also callable without instantiating the class, but its definition follows Subclass, not Parent class, via inheritance.

MyClass.classmethod()

Output:

Class method called

So when to use class methods?

@classmethod are for when you need to have methods that aren't specific to any particular instance, but still, involve the class in some way. The most interesting thing about them is that they can be overridden by subclasses.

So If you want to access a property of a class as a whole, and not the property of a specific instance of that class, use a class method.

class MyClass():
    TOTAL_OBJECTS=0
    def __init__(self):
        MyClass.TOTAL_OBJECTS = MyClass.TOTAL_OBJECTS+1

    @classmethod
    def total_objects(cls):
        print("Total objects: ",cls.TOTAL_OBJECTS)

# Creating objects
my_obj1 = MyClass()
my_obj2 = MyClass()
my_obj3 = MyClass()

# Calling class method
MyClass.total_objects()

Output:

Total objects:  3

Now if we inherit this class into a child class and declare the TOTAL_OBJECTS variable there and call the class method from child class it will return the total object count for the child class.

class MyClass():
    TOTAL_OBJECTS=0
    def __init__(self):
        MyClass.TOTAL_OBJECTS = MyClass.TOTAL_OBJECTS+1

    @classmethod
    def total_objects(cls):
        print("Total objects: ",cls.TOTAL_OBJECTS)

# Creating objects of parent 
classmy_obj1 = MyClass()
my_obj2 = MyClass()

# Creating a child class
class ChildClass(MyClass):
    TOTAL_OBJECTS=0
    passChildClass.total_objects()

Output:

Total objects:  0
Wrapping it up

@classmethod is used in a superclass to define how that method should behave when it's called by different child classes. Whereas a @staticmethod is used when we want to return the same thing regardless of the child class that we are calling.

Also, keep a note that calling a @classmethod involves an additional memory allocation that calling a @staticmethod or regular function does not.


PYTHON

Latest Articles

Latest from djangocentral

How to Use Subquery() in Django With Practical Examples

In the realm of web development, Django stands as a powerful and versatile framework for building robust applications. One of the key aspects of developing efficient and optimized web applications is handling database queries effectively. In this article…
Read more →

4 min read

DRF Serializer: Handling OrderedDict and Converting It to a Dictionary or JSON

In Django Rest Framework (DRF) tests, when you access serializer.data, you might encounter an OrderedDict instead of a regular dictionary. This behavior is intentional and reflects the design of DRF's serialization process.Understanding the Problem The u…
Read more →

3 min read

Django Rest Framework CheetSheet: Mastering API Development

Django Rest Framework (DRF) is a powerful toolkit that makes building robust and scalable web APIs with Django a breeze. Whether you're a seasoned Django developer or a newcomer, having a comprehensive cheat sheet at your disposal can be a game-changer. …
Read more →

5 min read

How to Perform NOT Queries in Django ORM

In Django, performing NOT queries allows you to exclude certain records from the query results based on specific conditions. The NOT operator, represented by the tilde (~) when used in conjunction with the Django ORM's Q object, helps you construct compl…
Read more →

3 min read