11.09.2020       Выпуск 351 (07.09.2020 - 13.09.2020)       Статьи

Объяснение @classmethod и @staticmethod в Python

Перевод: Python’s @classmethod and @staticmethod Explained

Для новичков, изучающих объектно-ориентированное программирование на Python, очень важно хорошо разбираться в таких понятиях как classmethod и staticmethod для написания более оптимизированного и повторно используемого кода.

Кроме того, даже опытные программисты, работающие на разных языках, часто путают эти два понятия.

Читать>>




Экспериментальная функция:

Ниже вы видите текст статьи по ссылке. По нему можно быстро понять ссылка достойна прочтения или нет

Просим обратить внимание, что текст по ссылке и здесь может не совпадать.

Перевод: Python’s @classmethod and @staticmethod Explained

Для новичков, изучающих объектно-ориентированное программирование на Python, очень важно хорошо разбираться в таких понятиях как classmethod и staticmethod для написания более оптимизированного и повторно используемого кода.

Кроме того, даже опытные программисты, работающие на разных языках, часто путают эти два понятия.

В этой статье мы разберем что это такое и какая между ними разница.

staticmethod в Python

@staticmethod — используется для создания метода, который ничего не знает о классе или экземпляре, через который он был вызван. Он просто получает переданные аргументы, без неявного первого аргумента, и его определение неизменяемо через наследование.

Проще говоря, @staticmethod — это вроде обычной функции, определенной внутри класса, которая не имеет доступа к экземпляру, поэтому ее можно вызывать без создания экземпляра класса.

Синтаксис:

class ClassName:
    @staticmethod
    def method_name(arg1, arg2, ...): ...

Здесь мы используем декоратор @staticmethod для определения статического метода в Python. Вы можете заметить, что статический метод не принимает self в качестве первого аргумента для метода.

А теперь посмотрим на пример использования.

class Myclass():
    @staticmethod
    def staticmethod():
        print('static method called')

Как мы уже говорили, мы можем получить доступ к статическому методу класса без создания экземпляра.

Myclass.staticmethod()

Результат:

static method called

Хотя вызов метода из экземпляра класса тоже возможен.

my_obj = Myclass()
my_obj.staticmethod()

Результат:

static method called

Отлично, но когда полезны статические методы?

Статический метод помогает в достижении инкапсуляции в классе, поскольку он не знает о состоянии текущего экземпляра. Кроме того, статические методы делают код более читабельным и повторно используемым, а также более удобным для импорта по сравнению с обычными функциями, поскольку каждую функцию не нужно отдельно импортировать.

class Person():
    @staticmethod
    def is_adult(age):
        if age > 18:
            return True
        else:
            return False

В приведенном выше примере мы можем проверить, является ли человек взрослым, без инициирование создания экземпляра.

Person.is_adult(23)

Результат:

True

Classmethod в Python

@classmethod — это метод, который получает класс в качестве неявного первого аргумента, точно так же, как обычный метод экземпляра получает экземпляр. Это означает, что вы можете использовать класс и его свойства внутри этого метода, а не конкретного экземпляра.

Проще говоря, @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 или обычной функции.






Разместим вашу рекламу

Пиши: mail@pythondigest.ru

Нашли опечатку?

Выделите фрагмент и отправьте нажатием Ctrl+Enter.

Система Orphus