Ответ
Декораторы @classmethod
и @staticmethod
в Python используются для определения методов внутри класса, но с разными целями и поведением относительно доступа к экземпляру или классу.
@classmethod
- Назначение: Определяет метод, который привязан к классу, а не к его экземпляру.
- Аргументы: Принимает первым аргументом сам класс (
cls
), а не экземпляр (self
). - Доступ: Имеет доступ к атрибутам класса и может изменять их. Может создавать новые экземпляры класса.
- Применение:
- Фабричные методы: Создание экземпляров класса с использованием альтернативных способов инициализации.
- Изменение состояния класса: Операции, которые влияют на все экземпляры класса или на сам класс.
Пример:
class Car:
wheels = 4 # Атрибут класса
def __init__(self, brand):
self.brand = brand
@classmethod
def set_wheels(cls, count):
"""Метод класса для изменения атрибута класса."""
cls.wheels = count
print(f"Количество колес изменено на {cls.wheels}")
@classmethod
def from_string(cls, car_string):
"""Фабричный метод для создания объекта Car из строки."""
brand, _ = car_string.split('-')
return cls(brand)
my_car = Car("Toyota")
print(f"Изначально колес: {Car.wheels}") # 4
Car.set_wheels(6) # Вызов через класс
print(f"После изменения колес: {Car.wheels}") # 6
new_car = Car.from_string("BMW-X5")
print(f"Создан автомобиль: {new_car.brand}, колес: {new_car.wheels}")
@staticmethod
- Назначение: Определяет метод, который не привязан ни к экземпляру, ни к классу. Он ведет себя как обычная функция, но логически принадлежит классу.
- Аргументы: Не принимает
self
илиcls
автоматически. - Доступ: Не имеет доступа к атрибутам экземпляра или класса (если только они не переданы явно как аргументы).
- Применение:
- Утилитарные функции: Функции, которые выполняют какую-то операцию, связанную с классом, но не требуют доступа к его внутреннему состоянию.
- Группировка: Для логической группировки функций внутри класса, когда они не зависят от состояния объекта или класса.
Пример:
class MathUtils:
@staticmethod
def add(a, b):
"""Статический метод для сложения двух чисел."""
return a + b
@staticmethod
def multiply(a, b):
"""Статический метод для умножения двух чисел."""
return a * b
print(f"Сумма: {MathUtils.add(5, 3)}") # Вызов через класс
print(f"Произведение: {MathUtils.multiply(4, 2)}")
Ключевые отличия
Характеристика | @classmethod |
@staticmethod |
---|---|---|
Первый аргумент | cls (ссылка на класс) |
Нет (self или cls не передаются) |
Доступ | К атрибутам класса | Ни к атрибутам класса, ни к экземпляра |
Назначение | Фабричные методы, изменение состояния класса | Утилитарные функции, логическая группировка |
Зависимость | Зависит от класса | Независим от класса и экземпляра |