When studying Python, you inevitably face the problem of choosing between static methods (@staticmethod), class methods (@classmethod), and module-level functions. In this article, I would like to deal with this issue.
From a technical point of view, the only difference between static and class methods is that the class method gets the class as the first argument.
Consider a simple example:
class Number:
    def __init__(self, value):
        self.value = value
    @classmethod
    def multiply(cls, x, y):
        return cls(x*y)
    @staticmethod
    def divide(x, y):
        return Number(x // y)
In this example, the Number class has two methods: a class method multiply and a static one divide. And we can successfully call both of these methods and it will all work.
>>> n = Number.multiply(1, 2)
>>> n.print()
2
>>> type(n)
<class '__main__.Number'>
>>> n = Number.divide(2, 1)
>>> n.print()
2
>>> type(n)
<class '__main__.Number'>
But what will happen if an inheritance is used?
For example:
class Real(Number):
    pass
The class Real will inherit all the methods of Number, but when we access the divide method, we will not get exactly what we might expect.
>>> r = Real.multiply(1, 2)
>>> r.print()
2
>>> type(r)
<class '__main__.Real'>
>>> r = Real.divide(2, 1)
>>> r.print()
2
>>>type(r)
<class '__main__.Number'>
As we can see, the divide method will return a Number instance instead of Real. To solve this problem, @classmethod-s are just right.
class Number:
    def __init__(self, value):
        self.value = value
    @classmethod
    def divide(cls, x, y):
        return cls(x // y)
    def print(self):
        print(self.value)
class Real(Number): pass
>>> r = Real.divide(2, 1)
>>> r.print()
2
>>>type(r)
<class '__main__.Real'>
So when is it better to use a class method, when a static method, and when a module-level function?
I believe that if a function needs access to a class, then it is a class method, if it does not need access to either the class or an instance of the class, but is logically related to the class, then it is a static method, otherwise, it is a module-level function.