Question: What do `@classmethod` and `@staticmethod` mean in Python, and how are they different? *When* should I use them, *why* should I use them, and *how* should I use them?

As far as I understand, `@classmethod` tells a class that it's a method which should be inherited into subclasses, or... something. However, what's the point of that? Why not just define the class method without adding `@classmethod` or `@staticmethod` or any `@` definitions?

Answer: 
***A little compilation***

**@staticmethod**
A way to write a method inside a class without reference to the object it is being called on. So no need to pass implicit argument like self or cls.
It is written exactly the same how written outside the class, but it is not of no use in python because if you need to encapsulate a method inside a class since this method needs to be the part of that class @staticmethod is comes handy in that case.

**@classmethod**
It is important when you want to write a factory method and by this custom attribute(s) can be attached in a class. This attribute(s) can be overridden in the inherited class.

A comparison between these two methods can be as below

[![Table](https://i.stack.imgur.com/LUyfq.png)](https://i.stack.imgur.com/LUyfq.png)
In short, @classmethod turns a normal method to a factory method.

Let's explore it with an example:

```
class PythonBook:
    def __init__(self, name, author):
        self.name = name
        self.author = author
    def __repr__(self):
        return f'Book: {self.name}, Author: {self.author}'

```

Without a @classmethod,you should labor to create instances one by one and they are scattered.

```
book1 = PythonBook('Learning Python', 'Mark Lutz')
In [20]: book1
Out[20]: Book: Learning Python, Author: Mark Lutz
book2 = PythonBook('Python Think', 'Allen B Dowey')
In [22]: book2
Out[22]: Book: Python Think, Author: Allen B Dowey

```

As for example with @classmethod

```
class PythonBook:
    def __init__(self, name, author):
        self.name = name
        self.author = author
    def __repr__(self):
        return f'Book: {self.name}, Author: {self.author}'
    @classmethod
    def book1(cls):
        return cls('Learning Python', 'Mark Lutz')
    @classmethod
    def book2(cls):
        return cls('Python Think', 'Allen B Dowey')

```

Test it:

```
In [31]: PythonBook.book1()
Out[31]: Book: Learning Python, Author: Mark Lutz
In [32]: PythonBook.book2()
Out[32]: Book: Python Think, Author: Allen B Dowey

```

See? Instances are successfully created inside a class definition and they are collected together.

In conclusion, @classmethod decorator convert a conventional method to a factory method,Using classmethods makes it possible to add as many alternative constructors as necessary.