Ответ
Основное различие заключается в том, какой контекст (объект) передается методу в качестве первого неявного аргумента, и, как следствие, к каким данным метод имеет доступ.
| Аспект | Метод класса (@classmethod) |
Статический метод (@staticmethod) |
|---|---|---|
| Первый аргумент | cls — ссылка на сам класс. |
Нет неявного аргумента. Принимает только явно переданные. |
| Доступ к: | Атрибутам и другим методам класса (через cls). |
Только к переданным аргументам. Не имеет доступа ни к self, ни к cls. |
| Может изменять: | Состояние класса (например, классовые переменные). | Ничего, если не передано явно. |
| Основное назначение | Альтернативные конструкторы, методы, работающие с классом как целым. | Вспомогательные функции, логически связанные с классом, но не требующие доступа к его состоянию. |
Практический пример на Python:
class Order:
tax_rate = 0.20 # Ставка НДС — атрибут класса
def __init__(self, amount):
self.amount = amount
@classmethod
def from_string(cls, order_str):
# Альтернативный конструктор: создает объект из строки
amount = float(order_str.replace('USD', ''))
return cls(amount) # Вызывает __init__
@classmethod
def update_tax_rate(cls, new_rate):
# Меняет атрибут, общий для всех экземпляров
cls.tax_rate = new_rate
@staticmethod
def format_currency(value):
# Вспомогательная функция, не зависящая от класса или экземпляра
return f"{value:.2f} USD"
def calculate_total(self):
return self.amount * (1 + self.tax_rate)
# Использование:
order1 = Order.from_string("100.50 USD") # Создание через classmethod
print(order1.calculate_total()) # 120.60
Order.update_tax_rate(0.18) # Меняем ставку для всех заказов
print(Order.format_currency(150)) # "150.00 USD" - вызов staticmethod
Таким образом, classmethod используется, когда логика метода привязана к классу, а staticmethod — когда это просто удобное место для размещения функции, связанной с предметной областью класса.