Получить доступ

Чем @staticmethod отличается от @classmethod?

JuniorООП
Ещё спрашивают так:
  • Когда использовать classmethod?
  • Зачем нужен staticmethod?
  • Что такое альтернативный конструктор?
Коротко

@classmethod получает класс (cls), @staticmethod не получает ничего — это обычная функция внутри класса.

  • classmethod — для альтернативных конструкторов: User.from_json(...)
  • При наследовании cls — это подкласс, поэтому создаётся объект нужного типа

А ещё staticmethod уместен, когда функция логически относится к классу, но не трогает его состояние

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Есть три вида методов:

  • обычный — первым аргументом получает экземпляр (self), работает с его данными;
  • **@classmethod** — первым аргументом получает класс (cls). Может создавать экземпляры и работать с атрибутами класса. Вызывается и от класса, и от экземпляра;
  • **@staticmethod** — не получает ни экземпляра, ни класса. По сути функция, положенная в пространство имён класса.

Главное применение classmethod — альтернативные конструкторы: datetime.fromtimestamp, dict.fromkeys. Важная деталь: если наследник вызовет Child.from_json(...), в cls придёт Child, и метод создаст объект наследника. С staticmethod так не получится — пришлось бы жёстко написать имя класса.

staticmethod используют для вспомогательных функций, тесно связанных с классом: проверка формата, преобразование значения. Если функция с классом не связана — ей место на уровне модуля.

Пример

import json

class User:
    def __init__(self, name, age):
        self.name, self.age = name, age

    @classmethod
    def from_json(cls, raw):
        data = json.loads(raw)
        return cls(data["name"], data["age"])   # cls — User или наследник

    @staticmethod
    def is_adult(age):
        return age >= 18

class Admin(User):
    pass

a = Admin.from_json('{"name": "Ира", "age": 30}')
type(a)               # Admin
User.is_adult(17)     # False

Что хотят услышать

  • Что получает каждый вид метода первым аргументом.
  • Альтернативный конструктор как главный случай classmethod.
  • Поведение cls при наследовании.
  • Когда staticmethod уместен, а когда лучше функция модуля.

Частые ошибки

  • Писать фабрику через staticmethod с жёстким именем класса.
  • Говорить, что staticmethod нельзя вызвать от экземпляра.

Что спросят дальше

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем