2023-02-24

Classmethod and Staticmethod in Python

What is a Classmethod

In Python, classmethod is a built-in decorator that can be used to define a method that belongs to a class and not to an instance of the class. This means that a classmethod can be called on the class itself rather than on an instance of the class.

The main purpose of a classmethod is to allow the class to modify or access its own class-level state. This can be useful for creating alternative constructors for a class, or for implementing factory methods that return instances of the class.

To define a classmethod, you need to add the @classmethod decorator before the method definition. The first parameter of the method should be cls, which refers to the class itself. Here is an example:

python
class MyClass:
    class_variable = 10

    @classmethod
    def class_method(cls, x):
        return cls.class_variable * x

result = MyClass.class_method(5)
print(result)  # Output: 50

In this example, class_variable is a class-level variable that can be accessed and modified by the classmethod class_method(). The class_method() takes a parameter x, multiplies it with class_variable and returns the result.

In summary, classmethod is a powerful tool in Python that allows you to define methods that belong to a class rather than an instance of the class. It is commonly used to create alternative constructors or factory methods, and to modify or access class-level state.

What is a Staticmethod

Python provides the built-in staticmethod decorator, which allows you to define methods that belong to a class but don't require access to any instance or class-level state. Let's take a look at an example of how to use staticmethod.

Suppose we have a Person class that represents a person and we want to define a method that takes in two dates and returns the difference between them in years. This method doesn't need to access any instance or class-level state, so it's a good candidate for a staticmethod.

python
import datetime

class Person:
    def __init__(self, name, birthdate):
        self.name = name
        self.birthdate = birthdate

    @staticmethod
    def calculate_age(birthdate, today):
        age = today.year - birthdate.year - ((today.month, today.day) < (birthdate.month, birthdate.day))
        return age

person1 = Person("John", datetime.date(1990, 1, 1))
today = datetime.date.today()

age = Person.calculate_age(person1.birthdate, today)
print(f"{person1.name} is {age} years old.")

In this example, we defined a calculate_age method as a staticmethod. This method takes in two dates, birthdate and today, and calculates the difference between them in years using a simple algorithm.

We then created a Person object with a name and birthdate and retrieved the current date using the datetime.date.today() method. We called the calculate_age method on the Person class and passed in the birthdate of the Person object and the current date to get the age in years. Finally, we printed out the name of the person and their age.

By using a staticmethod, we were able to define a method that belongs to the Person class but doesn't require access to any instance or class-level state. This makes the code more organized and readable.

Comparison of Classmethod and Staticmethod

While classmethod and staticmethod may seem similar at first, there are some key differences between the two.

classmethod is used when you want a method to operate on the class itself rather than on instances of the class. It takes the class as its first argument, typically called cls. This allows you to access class-level state and create new instances of the class as needed.

On the other hand, staticmethod is used when you want a method to belong to a class but not to any specific instance of the class. It does not take the class as an argument and does not have access to class-level state. It is often used for utility functions that are related to the class, but do not require access to any instance-level state.

Here is a comparison of the two methods:

  • Signature

    • classmethod takes a cls parameter as the first argument, which represents the class itself.
    • staticmethod does not take any special parameter.
  • Accessing lass-level state

    • classmethod can access class-level state via the cls parameter.
    • staticmethod cannot access class-level state.
  • Creating new instances

    • classmethod can create new instances of the class via the cls parameter.
    • staticmethod cannot create new instances of the class.
  • Inheritance

    • classmethod is inherited by subclasses and can be overridden.
    • staticmethod is also inherited by subclasses, but cannot be overridden.

Here's an example to illustrate the differences:

python
class MyClass:
    class_var = "class variable"

    def __init__(self, inst_var):
        self.inst_var = inst_var

    @classmethod
    def from_class_method(cls, inst_var):
        return cls(inst_var + " (created by classmethod)")

    @staticmethod
    def from_static_method(inst_var):
        return MyClass(inst_var + " (created by staticmethod)")

instance = MyClass("instance variable")
instance2 = MyClass.from_class_method("instance variable")
instance3 = MyClass.from_static_method("instance variable")

print(instance.class_var)  # "class variable"
print(instance2.class_var)  # "class variable"
print(instance3.class_var)  # "class variable"

print(instance.inst_var)  # "instance variable"
print(instance2.inst_var)  # "instance variable (created by classmethod)"
print(instance3.inst_var)  # "instance variable (created by staticmethod)"

In this example, we defined a MyClass with a class_var and an inst_var. We then defined a classmethod and a staticmethod that create new instances of the class.

When we call the from_class_method method, it creates a new instance of the class with the given inst_var and returns it. When we call the from_static_method method, it creates a new instance of the class and returns it.

As we can see from the output, both methods can access the class variable, but only the classmethod can access and create new instances of the class.

References

https://www.geeksforgeeks.org/class-method-vs-static-method-python/

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!