classmethod

Функция classmethod() преобразует метод класса в метод, который может быть вызван как на самом классе, так и на его экземплярах. Метод, декорированный с помощью @classmethod, получает класс (а не экземпляр) в качестве первого аргумента.

Синтаксис

classmethod(function)

@classmethod

Аргументы

  • function:
    • Что означает: Метод, который нужно преобразовать в метод класса.
    • Возможные значения: Любая вызываемая функция.

Возвращаемое значение

Возвращает объект classmethod. Обычно используется как декоратор.

Примеры использования

# Простой пример
class MyClass:
    class_attribute = "Я атрибут класса"

    @classmethod
    def get_class_attribute(cls):
        return cls.class_attribute

print(MyClass.get_class_attribute())  # Вывод: Я атрибут класса
# Использование classmethod для создания альтернативного конструктора
class MyClass:
    def __init__(self, value):
        self.value = value

    @classmethod
    def from_string(cls, value_str):
        value = int(value_str)
        return cls(value)

obj = MyClass.from_string("42")
print(obj.value)  # Вывод: 42
# Доступ к методам класса из экземпляра
class MyClass:
    @classmethod
    def say_hello(cls):
        return f"Привет от {cls.__name__}!"

obj = MyClass()
print(obj.say_hello())  # Вывод: Привет от MyClass!

Эквивалентный код

class classmethod:
    def __init__(self, func):
        self.func = func

    def __get__(self, instance, owner):
        return lambda *args, **kwargs: self.func(owner, *args, **kwargs)

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

  1. Попытка использовать classmethod для методов экземпляра:

    class MyClass:
        def __init__(self, value):
            self.value = value
    
        @classmethod
        def instance_method(self):
            return self.value  # Это вызовет ошибку, так как 'self' не существует в методе класса
    

    Решение: Методы класса не могут использовать атрибуты экземпляра.

Часто задаваемые вопросы

  1. Чем отличается classmethod от обычного метода? Обычный метод получает экземпляр (self) как первый аргумент, а classmethod получает класс (cls).

  2. Может ли classmethod работать с экземплярами? Да, экземпляры могут вызывать методы класса, так как cls всегда ссылается на сам класс.

  3. Можно ли использовать classmethod для создания альтернативных конструкторов? Да, это одна из наиболее распространённых практик:

    class MyClass:
        def __init__(self, value):
            self.value = value
    
        @classmethod
        def from_tuple(cls, values):
            return cls([value for value in values])
    
    obj = MyClass.from_tuple((1, 2, 3))
    print(obj.value)  # Вывод: [1, 2, 3]
    
  4. Что произойдёт, если вызвать classmethod у дочернего класса? Если метод не переопределён в подклассе, то будет использоваться метод родительского класса.