Ответ
Основное различие заключается в первом аргументе, который они получают (или не получают), что определяет их возможности.
Статический метод (@staticmethod)
Не получает никаких обязательных первых аргументов (self или cls). Это, по сути, обычная функция, помещенная в пространство имен класса для логической группировки. Она не может изменять состояние класса или экземпляра.
Класс-метод (@classmethod)
Получает класс в качестве первого неявного аргумента, который по соглашению называется cls. Это позволяет методу работать с самим классом, например, обращаться к его атрибутам или создавать экземпляры класса (фабричные методы).
Сравнительный пример:
class MyClass:
class_variable = 10
def __init__(self, value):
self.instance_variable = value
@staticmethod
def static_method(x, y):
# Не имеет доступа ни к class_variable, ни к instance_variable
# Просто утилитарная функция
return x + y
@classmethod
def class_method(cls, value_for_new_instance):
# Имеет доступ к атрибутам класса, например, cls.class_variable
print(f"Class variable: {cls.class_variable}")
# Может создавать экземпляры класса (фабричный метод)
return cls(value_for_new_instance)
# Вызов без создания экземпляра
print(MyClass.static_method(5, 3)) # Вывод: 8
# Создание экземпляра через класс-метод
instance = MyClass.class_method(100)
print(instance.instance_variable) # Вывод: 100
Когда что использовать:
@staticmethod: для утилитарных функций, которые логически связаны с классом, но не зависят от его состояния.@classmethod: для создания альтернативных конструкторов (фабричных методов) или для операций, которые должны работать с классом в целом.
Ответ 18+ 🔞
Вот же ж, опять эти статические методы с класс-методами путают, как будто это одно и то же! Слушай, давай разберёмся, пока мозг не закипел, как чайник.
Представь себе класс — это типа такой дом. Внутри живут обычные методы (они же инстанс-методы), которые знают про конкретную квартиру (self). А ещё там есть два особенных жильца.
Первый — статик-метод (@staticmethod).
Это такой отшельник, блядь. Ему похуй на весь дом. Ни тебе self, ни cls он не получает. Вообще. Ноль. Просто функция, которую для порядка в шкаф к классу засунули, чтобы не валялась где попало. Изменить состояние класса или экземпляра? Да ни хуя! Он как калькулятор: дали два числа — получи результат.
Второй — класс-метод (@classmethod).
А вот этот парень — завхоз. Он получает на вход сам класс, то есть весь дом целиком. По договорённости этот аргумент зовут cls. И он с этим домом может делать штуки: заглянуть в общие настройки (атрибуты класса) или, например, новых жильцов (экземпляры) создавать. Фабричные методы — это его конёк, ёпта.
Смотри, как это в коде выглядит, чтоб совсем понятно стало:
class MyClass:
class_variable = 10 # Общая для всех тарелка с печеньками
def __init__(self, value):
self.instance_variable = value # А это личная печенька
@staticmethod
def static_method(x, y):
# Ему вообще похуй на печеньки, свои или общие.
# Просто сложит что дали и всё.
return x + y
@classmethod
def class_method(cls, value_for_new_instance):
# Опа, а этот видит общую тарелку!
print(f"Class variable: {cls.class_variable}")
# И может новых чуваков в дом заселить (экземпляр создать)
return cls(value_for_new_instance)
# Вызываем отшельника-статик. Ему даже экземпляр не нужен.
print(MyClass.static_method(5, 3)) # Вывод: 8. Просто математика, блядь.
# А тут завхоз-классметод работает. Создаёт нам новый экземпляр.
instance = MyClass.class_method(100)
print(instance.instance_variable) # Вывод: 100. Новый жилец с личной печенькой.
Так когда что юзать, чтобы не выглядеть как манда с ушами?
@staticmethod: Когда у тебя есть утилитарная функция, которая по смыслу привязана к классу, но ей наплевать на его внутреннее состояние. Типаcalculate_distance(x1, y1, x2, y2)внутри классаPoint. Чистая логика, без доступа кselfилиcls.@classmethod: Когда тебе нужно работать с классом как с объектом. Самый частый случай — это альтернативные конструкторы (фабрики). Например,from_json(cls, data)илиcreate_default(cls). Или когда метод должен обращаться к атрибутам класса, а не экземпляра.
Вот и вся магия, ёбушки-воробушки. Главное — не путай их, а то получится пиздопроебибна, а не код.