Зачем использовать classmethod вместо staticmethod?

Я знаю, что они делают, и видел много примеров того и другого, но я не нашел ни одного примера, в котором мне пришлось бы использовать classmethod вместо замены его на staticmethod.

Самый распространенный пример classmethod, который я видел, - это для создания нового экземпляра самого класса, как этот (очень упрощенный пример, метод atm не используется, но вы поняли идею):

class Foo:
    @classmethod
    def create_new(cls):
        return cls()

Это вернет новый экземпляр Foo при вызове foo = Foo.create_new(). Теперь почему я не могу просто использовать это вместо этого:

class Foo:
    @staticmethod
    def create_new():
        return Foo()

Он делает то же самое, зачем мне использовать classmethod вместо staticmethod?


person Patrik Lippojoki    schedule 23.04.2013    source источник


Ответы (3)


В вашем примере небольшая разница, но предположим, что вы создали подкласс Foo и вызвали метод create_new для подкласса ...

class Bar(Foo):
    pass

obj = Bar.create_new()

... тогда этот базовый класс вызовет создание нового Bar объекта ...

class Foo:
    @classmethod
    def create_new(cls):
        return cls()

... тогда как этот базовый класс вызовет создание нового объекта Foo ...

class Foo:
    @staticmethod
    def create_new():
        return Foo()

... поэтому выбор будет зависеть от того, какое поведение вы хотите.

person Aya    schedule 23.04.2013

Да, эти два класса будут делать то же самое.

Однако теперь представьте себе подтип этого класса:

class Bar (Foo):
    pass

Теперь вызов Bar.create_new делает что-то другое. Для статического метода вы получите Foo. Для метода класса вы получите Bar.

Таким образом, важное отличие состоит в том, что метод класса получает тип, переданный в качестве параметра.

person poke    schedule 23.04.2013

Из документации метод класса получает свой класс в качестве неявного аргумента, в то время как статические методы не знают, в каком классе они находятся.

Это может быть полезно в ситуациях, когда у вас есть унаследованный статический метод, который вы хотите переопределить другим поведением в подклассе.

person dckrooney    schedule 23.04.2013