@classmethod — это метод, который принимает класс в качестве неявного первого аргумента, точно так же, как обычный метод экземпляра получает экземпляр.
Это означает, что вы можете использовать класс и его свойства внутри этого метода, а не в конкретном экземпляре.
Простыми словами, @classmethod
— это обычный метод класса, который имеет доступ ко всем атрибутам класса, из которого он был вызван. Таким образом, метод класса является методом, связанным с классом, а не экземпляром класса.
Синтаксис метода:
class Class:
@classmethod
def method(cls, arg1, arg2, ...):
...
В данному случае декоратор @classmethod
используется для создания методов класса, и cls должен быть первым аргументом каждого метода класса.
class MyClass:
@classmethod
def classmethod(cls):
print('Class method called')
Функцию classmethod также можно вызывать без создания экземпляра класса, но его определение следует за подклассом, а не за родительским классом, через наследование.
MyClass.classmethod()
Результат:
Class method called
Когда использовать classmethod?
@classmethod
используется, когда вам нужно получить методы, которые не относятся к конкретному экземпляру, но все же каким-то образом связаны с классом. Самое интересное в них то, что они могут быть переопределены дочерними классами.
Итак, если вы хотите получить доступ к свойству класса в целом, а не к свойству конкретного экземпляра этого класса, используйте classmethod.
class MyClass():
TOTAL_OBJECTS=0
def __init__(self):
MyClass.TOTAL_OBJECTS = MyClass.TOTAL_OBJECTS+1
@classmethod
def total_objects(cls):
print("Total objects: ",cls.TOTAL_OBJECTS)
# Создаем объекты
my_obj1 = MyClass()
my_obj2 = MyClass()
my_obj3 = MyClass()
# Вызываем classmethod
MyClass.total_objects()
Результат выполнения:
Total objects: 3
Теперь, если мы унаследуем этот класс в дочерний класс и объявим там переменную TOTAL_OBJECTS и вызовем метод класса из дочернего класса, он вернет общее количество объектов для дочернего класса.
class MyClass():
TOTAL_OBJECTS=0
def __init__(self):
MyClass.TOTAL_OBJECTS = MyClass.TOTAL_OBJECTS+1
@classmethod
def total_objects(cls):
print("Total objects: ", cls.TOTAL_OBJECTS)
# Создаем объекты родительского класса
my_obj1 = MyClass()
my_obj2 = MyClass()
# Создаем дочерний класс
class ChildClass(MyClass):
TOTAL_OBJECTS=0
pass
ChildClass.total_objects()
Результат:
Total objects: 0
Заключение
@classmethod
используется в суперклассе для определения поведения метода при вызове из разных дочерних классов. Принимая во внимание, что @staticmethod
используется, когда мы хотим вернуть одно и то же независимо от вызываемого дочернего класса.
Также имейте в виду, что вызовы @classmethod
требуют дополнительного выделения памяти, чего нельзя сказать о @staticmethod
или вызовах обычных функций.
Источник: webdevblog.ru