Зачем использовать 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
?
Ответы
Ответ 1
В вашем примере мало различий, но предположим, что вы создали подкласс 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()
... поэтому выбор будет зависеть от того, какое поведение вы хотите.
Ответ 2
Да, эти два класса будут делать то же самое.
Однако теперь представьте подтип этого класса:
class Bar (Foo):
pass
Теперь вызов Bar.create_new
делает что-то другое. Для статического метода вы получаете Foo
. Для метода класса вы получите Bar
.
Таким образом, важное различие заключается в том, что метод класса получает тип, переданный как параметр.
Ответ 3
Из docs метод класса получает свой класс как неявный аргумент, тогда как статические методы не знают о классе, в котором они проживают.
Это может быть полезно в ситуациях, когда у вас есть унаследованный статический метод, который вы хотите переопределить с другим поведением в подклассе.