Чем @classmethod помогает сделать «альтернативный конструктор»?
Постоянно встречаю в библиотеках штуки вроде datetime.fromtimestamp(...) или dict.fromkeys(...) — создаёшь объект не через обычный __init__, а через метод класса. Как сделать такой «второй конструктор» у своего класса и зачем это вообще нужно?
2 ответа
Альтернативный конструктор — это @classmethod, который принимает данные в другом формате, сам создаёт и возвращает экземпляр. Первый аргумент — cls (сам класс), через него и создаётся объект:
class Date:
def __init__(self, day, month, year):
self.day = day
self.month = month
self.year = year
@classmethod
def from_string(cls, s):
day, month, year = map(int, s.split('.'))
return cls(day, month, year)
d = Date.from_string('16.06.2026')
Зачем cls, а не имя класса прямо? Потому что при наследовании cls подставит класс-наследника, и from_string создаст правильный тип автоматически. Это удобно, когда объект можно собрать из разных источников (строка, словарь, JSON, таймстамп), а захламлять один __init__ кучей if не хочется.
Через @classmethod с cls. Он создаёт объект из «нестандартных» входных данных и возвращает его. Удобно, чтобы не пихать кучу веток в __init__.