Q:

Can @classmethod be substituted using @staticmethod and returning an instance of the class?

I was reading this tutorial on  @classmethod and @staticmethod, I am not sure why is necessary to use @classmethod. I can have the same result using @staticmethod and returning an instance of the class, following the example of the tutorial:
class Pizza:
    def __init__(self, ingredients):
        self.ingredients = ingredients

    @classmethod
    def prosciutto(cls):
        return cls(['mozzarella', 'tomatoes', 'ham'])

    @staticmethod
    def prosciutto2():
        return Pizza(['mozzarella', 'tomatoes', 'ham'])

I was wondering if there is any difference between this two implementations:
p = Pizza.prosciutto() 
p1 = Pizza.prosciutto2()

Can a static method that returns an instance of its own class be used instead of a class method without any disadvantage?

A:

When there's only a single class, like in your example, then either a classmethod or a staticmethod (that names the class explicitly in its implementation) can work. But if you want to be able to extend the class in the future, you probably want to use classmethod.
Here's an example that builds on your code:
class ThinCrustPizza(Pizza):
   pass

If you call ThinCrustPizza.prosciutto(), you'll get an instance of ThinCrustPizza, not the base Pizza class it inherited the method from. That's because cls in the classmethod will be the class you called it on, which is the child class.
But if you call ThinCrustPizza.proscutto2(), you'll get the same Pizza instance you would get from calling it on Pizza, since the implementation needed to refer to Pizza by name. Because it doesn't get the class passed in, it can't tell that it was called on a subclass.

