Объяснение к уроку
После этого урока ты сможешь:
self), класс (cls) или ни то, ни другое.@classmethod для работы с информацией уровня класса или создания объектов.@staticmethod для вспомогательной функции, концептуально относящейся к классу.Обычный метод экземпляра начинается с self, текущего объекта. Ты уже использовал его для чтения и изменения атрибутов, созданных в __init__:
class Job:
def __init__(self, name):
self.name = name
def display_name(self):
return self.name.upper()Метод класса начинается с cls и помечается декоратором @classmethod. Он получает класс автоматически, независимо от того, вызываешь ли ты его через класс или через экземпляр. Методы класса удобны для чтения общих настроек или создания экземпляра из альтернативного формата входных данных.
Статический метод, помеченный декоратором @staticmethod, не получает self или cls автоматически. Используй его для тесно связанных вычислений или валидации, которым не требуется состояние объекта.
Эти аннотации используют синтаксис @..., но тебе пока не нужны универсальные декораторы. @classmethod и @staticmethod — это встроенные формы, необходимые в этом уроке.
cls ссылается на класс, поэтому результат использует его общую настройку.
class Mailer:
default_sender = "robot@example.com"
@classmethod
def sender(cls):
return cls.default_sender
print(Mailer.sender())Вывод:
robot@example.comВ отличие от метода экземпляра, этот метод можно вызвать без создания объекта Mailer.
Статический метод группирует служебную функцию с типом данных, к которому она относится. Он принимает только те параметры, которые ты объявил.
class PortRules:
@staticmethod
def is_allowed(port):
return 1 <= port <= 65535
print(PortRules.is_allowed(443))Вывод:
TrueЗдесь нет self или cls в is_allowed, так как метод использует только port.
Метод класса может предоставлять альтернативный способ создания валидного экземпляра.
class Badge:
def __init__(self, title):
self.title = title
@classmethod
def from_text(cls, raw_title):
return cls(raw_title.strip())
print(Badge.from_text(" Operator ").title)Вывод:
OperatorИспользование cls(...) создает экземпляр того класса, который вызвал метод.
Метод, использующий self, возвращает информацию о конкретном объекте.
class Subscription:
def __init__(self, plan, active):
self.plan = plan
self.active = active
def status(self):
if self.active:
return f"{self.plan}: active"
return f"{self.plan}: inactive"
print(Subscription("starter", False).status())Вывод:
starter: inactiveКаждая подписка может иметь различное состояние, поэтому здесь уместен метод экземпляра.
| Метод | Первый параметр | Получает автоматически | Частый сценарий |
|---|---|---|---|
| Метод экземпляра | self | Объект | Чтение/обновление атрибутов |
@classmethod | cls | Класс | Общие настройки, фабричные конструкторы |
@staticmethod | Никакой | Ничего | Связанная валидация, нормализация |
@classmethod с расчетом на то, что cls передастся автоматически.self, хотя вызывающий код передает только явные аргументы.self.setting, когда целью является изменение настройки, общей для всего класса.