staticmethod python 3 что это
Декораторы @classmethod и @staticmethod
Приветствую всех на внеочередном занятии по ООП. Меня часто спрашивают: чем отличаются обычные методы класса от методов, объявленных декораторами:
@classmethod и @staticmethod
Давайте разбираться. На уровне теории это выглядит так. Предположим, у нас есть класс Vector, который содержит два атрибута: MIN_COORD = 0, MAX_COORD = 100; обычный метод setCoords; метод уровня класса: validate и статический метод – norm2:
Так вот, все обычные методы в качестве первого параметра обязательно должны получать ссылку на экземпляр этого класса. И благодаря ей, они могут менять состояние как объекта класса, так и получать доступ к свойствами и методам самого класса Vector.
Когда метод класса объявляется через декоратор @classmethod, то первым параметром ему нужно передать сам класс, а не его экземпляр. В результате, такой метод может обращаться ко всем свойствам и методам текущего класса Vector, но не к экземпляру (из, которого он может быть вызван).
Наконец, третий тип методов, объявленные через декоратор @staticmethod, являются, своего рода, совершенно изолированными и от свойств и методов класса и, уж тем более, от свойств и методов экземпляра. Их можно воспринимать как отдельные, самостоятельные функции, объявленные внутри класса. Обычно, это делают для удобства, т.к. их функционал так или иначе связан с тематикой класса.
Итак, давайте на практике посмотрим, что все это значит. Я объявлю класс Vector вот в таком виде:
И для удобства открою консоль Python, где импортирую этот класс из модуля ex1:
Далее, смотрите, непосредственно через класс Vector можно вызвать метод класса:
Метод classmethod() и staticmethod в Python
Автор: Кольцов Д · Опубликовано 16.11.2020 · Обновлено 16.11.2020
Метод classmethod() возвращает метод класса для данной функции.
classmethod() считается не-Pythonic, поэтому в более новых версиях Python вы можете использовать декоратор @classmethod для определения метода класса.
Метод classmethod() принимает единственный параметр:
И возвращает метод класса для данной функции.
Что такое метод класса?
Метод класса — это метод, который привязан к классу, а не к его объекту. Он не требует создания экземпляра класса, как staticmethod.
Разница между статическим методом и методом класса:
Метод класса может вызываться как классом, так и его объектом.
Пример 1: Создать метод класса с помощью classmethod()
Здесь у нас есть класс Person с возрастом переменной, присвоенным 25. У нас также есть функция printAge, которая принимает единственный параметр cls, а не self, который мы обычно принимаем. cls принимает в качестве параметра класс Person, а не объект или экземпляр Person.
Теперь мы передаем метод Person.printAge в качестве аргумента методу класса функции. Это преобразует метод в метод класса, так что он принимает первый параметр как класс (т.е. Person).
В последней строке мы вызываем printAge без создания объекта Person, как мы это делаем для статических методов. Это печатает возраст переменной класса.
Когда вы использовать метод класса?
1 Фабричные методы
Фабричные методы — это те методы, которые возвращают объект класса (например, конструктор) для различных вариантов использования.
Это похоже на перегрузку функций в C ++. Поскольку в Python нет ничего как такового, используются методы классов и статические методы.
Пример 2: Создание фабричного метода с использованием метода класса
Здесь у нас есть два создателя экземпляра класса, конструктор и метод fromBirthYear.
Конструктор принимает обычные параметры name и age. В то время как fromBirthYear принимает класс, имя и год рождения, вычисляет текущий возраст, вычитая его из текущего года, и возвращает экземпляр класса.
Перед методом мы видим @classmethod. Это называется декоратором для преобразования fromBirthYear в метод класса как classmethod().
2 Правильное создание экземпляра в наследовании
Всякий раз, когда вы создаете класс из реализации фабричного метода как метода класса, это обеспечивает правильное создание экземпляра производного класса.
Вы можете создать статический метод для приведенного выше примера, но создаваемый им объект всегда будет закодирован как базовый класс.
Но когда вы используете метод класса, он создает правильный экземпляр производного класса.
Пример 3: Как метод класса работает для наследования?
Здесь использование статического метода для создания экземпляра класса требует от нас жесткого кодирования типа экземпляра во время создания.
fromFathersAge возвращает не объект Man, а объект его базового класса Person.
Это нарушает парадигму ООП. Использование метода класса от fromBirthYear может гарантировать ООП-кодирование кода, поскольку он принимает первый параметр как сам класс и вызывает его фабричный метод.
Встроенная функция staticmethod() возвращает статический метод для данной функции.
В более новых версиях Python вы можете использовать декоратор @staticmethod.
Метод staticmethod() принимает единственный параметр:
Staticmethod() возвращает статический метод для функции, переданной в качестве параметра.
Что такое статический метод?
Статические методы, как и методы класса, — это методы, привязанные к классу, а не к его объекту. Они не требуют создания экземпляра класса. Они не зависят от состояния объекта.
Разница между статическим методом и методом класса:
Их может вызывать как класс, так и его объект.
Создание статического метода с помощью staticmethod()
Когда использовать статические методы?
1. Группирование функции в класс
Статические методы имеют ограниченный вариант использования, потому что, как методы класса или любые другие методы внутри класса, они не могут получить доступ к свойствам самого класса.
Однако, когда вам нужна служебная функция, которая не имеет доступа к каким-либо свойствам класса, но имеет смысл, что она принадлежит этому классу, мы используем статические функции.
Создание служебной функции как статического метода
Здесь у нас есть класс Dates, который работает только с датами с тире. Однако в нашей предыдущей базе данных все даты были указаны в виде косой черты.
Чтобы преобразовать даты с косой чертой в даты с тире, мы создали служебную функцию toDashDate в Dates.
Это статический метод, потому что он не требует доступа к каким-либо свойствам самой даты, а требует только параметров.
Мы также можем создать toDashDate вне класса, но поскольку он работает только для дат, логично оставить его внутри класса Dates.
Наличие единой реализации
Статические методы используются, чтобы подклассы класса изменяли или переопределяли конкретную реализацию метода.
Как наследование работает со статическим методом?
Здесь мы не хотели бы, чтобы подкласс DatesWithSlashes переопределял статический служебный метод toDashDate, потому что он используется только один раз, то есть меняет дату на тире-даты.
Мы могли бы легко использовать статический метод в наших интересах, переопределив метод getDate() в подклассе, чтобы он хорошо работал с классом DatesWithSlashes.
Статический метод Python
Зачем нужны статические методы Python?
Статические методы позволяют разделить служебные методы на отдельные подмодули.
Допустим, у нас есть модуль Python для служебных методов для строк, списков и кортежей.
Мы можем создавать статические методы в отдельных классах для лучшего понимания и простоты использования.
Как создать статический метод в Python
Python предоставляет два способа создания статического метода.
1. Использование функции staticmethod()
Staticmethod() полезен, когда вы хотите создать статический метод, определенный в классе. Обратите внимание, что у метода не должно быть аргумента self.
Если мы попытаемся вызвать метод to_uppercase() из объекта StringUtils, он вызовет ошибку, поскольку «метод принимает 1 позиционный аргумент, но было дано 2».
Однако мы можем вызвать метод to_uppercase() из ссылки на класс.
2. Использование аннотации @staticmethod
Это рекомендуемый способ создания статического метода. Нам просто нужно аннотировать метод декоратором @staticmethod.
Статический метод и метода класса — сравнение
Сравнение статического метода и метода экземпляра
Преимущества
Статические методы полезны для группировки служебных методов внутри границ класса. В остальном это просто обычная функция в скрипте Python.
Объяснение @classmethod и @staticmethod в Python
Для новичков, изучающих объектно-ориентированное программирование на Python, очень важно хорошо разбираться в таких понятиях как classmethod и staticmethod для написания более оптимизированного и повторно используемого кода.
Кроме того, даже опытные программисты, работающие на разных языках, часто путают эти два понятия.
В этой статье мы разберем что это такое и какая между ними разница.
staticmethod в Python
@staticmethod — используется для создания метода, который ничего не знает о классе или экземпляре, через который он был вызван. Он просто получает переданные аргументы, без неявного первого аргумента, и его определение неизменяемо через наследование.
Проще говоря, @staticmethod — это вроде обычной функции, определенной внутри класса, которая не имеет доступа к экземпляру, поэтому ее можно вызывать без создания экземпляра класса.
Синтаксис:
Здесь мы используем декоратор @staticmethod для определения статического метода в Python. Вы можете заметить, что статический метод не принимает self в качестве первого аргумента для метода.
А теперь посмотрим на пример использования.
Как мы уже говорили, мы можем получить доступ к статическому методу класса без создания экземпляра.
Результат:
Хотя вызов метода из экземпляра класса тоже возможен.
Результат:
Отлично, но когда полезны статические методы?
Статический метод помогает в достижении инкапсуляции в классе, поскольку он не знает о состоянии текущего экземпляра. Кроме того, статические методы делают код более читабельным и повторно используемым, а также более удобным для импорта по сравнению с обычными функциями, поскольку каждую функцию не нужно отдельно импортировать.
В приведенном выше примере мы можем проверить, является ли человек взрослым, без инициирование создания экземпляра.
Результат:
Classmethod в Python
@classmethod — это метод, который получает класс в качестве неявного первого аргумента, точно так же, как обычный метод экземпляра получает экземпляр. Это означает, что вы можете использовать класс и его свойства внутри этого метода, а не конкретного экземпляра.
Проще говоря, @classmethod — это обычный метод класса, имеющий доступ ко всем атрибутам класса, через который он был вызван. Следовательно, classmethod — это метод, который привязан к классу, а не к экземпляру класса.
Синтаксис:
В данному случае декоратор @classmethod используется для создания методов класса, и cls должен быть первым аргументом каждого метода класса.
Функцию classmethod также можно вызывать без создания экземпляра класса, но его определение следует за подклассом, а не за родительским классом, через наследование.
Результат:
Когда использовать classmethod?
@classmethod используется, когда вам нужно получить методы, не относящиеся к какому-либо конкретному экземпляру, но тем не менее, каким-то образом привязанные к классу. Самое интересное в них то, что их можно переопределить дочерними классами.
Поэтому, если вы хотите получить доступ к свойству класса в целом, а не к свойству конкретного экземпляра этого класса, используйте classmethod.
Результат:
Теперь, если мы унаследуем этот класс в дочерний класс и объявим там переменную TOTAL_OBJECTS и вызовем метод класса из дочернего класса, он вернет общее количество объектов для дочернего класса.
Результат:
Заключение
@classmethod используется в суперклассе для определения того, как метод должен вести себя, когда он вызывается разными дочерними классами. В то время как @staticmethod используется, когда мы хотим вернуть одно и то же, независимо от вызываемого дочернего класса.
Также имейте в виду, что вызов @classmethod включает в себя дополнительное выделение памяти, чего нет при вызове @staticmethod или обычной функции.
Python: статические методы, методы класса и экземпляра класса
Согласно модели данных Python, язык предлагает три вида методов: статические, класса и экземпляра класса. Давайте посмотрим, что же происходит за кулисами каждого из видов методов. Понимание принципов их работы поможет в создании красивого и эффективного кода. Начнём с самого простого примера, в котором демонстрируются все три вида методов.
Методы экземпляра класса
Это наиболее часто используемый вид методов. Методы экземпляра класса принимают объект класса как первый аргумент, который принято называть self и который указывает на сам экземпляр. Количество параметров метода не ограничено.
Встроенный пример метода экземпляра — str.upper() :
Методы класса
Методы класса привязаны к самому классу, а не его экземпляру. Они могут менять состояние класса, что отразится на всех объектах этого класса, но не могут менять конкретный объект.
Встроенный пример метода класса — dict.fromkeys() — возвращает новый словарь с переданными элементами в качестве ключей.
Статические методы
Их можно воспринимать как методы, которые “не знают, к какому классу относятся”.
Таким образом, статические методы прикреплены к классу лишь для удобства и не могут менять состояние ни класса, ни его экземпляра.
С теорией достаточно. Давайте разберёмся с работой методов, создав объект нашего класса и вызвав поочерёдно каждый из методов: instancemethod, classmethod and staticmethod.
Теперь давайте вызовем метод класса:
Мы видим, что метод класса classmethod() имеет доступ к самому классу ToyClass, но не к его конкретному экземпляру объекта. Запомните, в Python всё является объектом. Класс тоже объект, который мы можем передать функции в качестве аргумента.
Заметьте, что self и cls — не обязательные названия и эти параметры можно называть иначе.
Это лишь общепринятые обозначения, которым следуют все. Тем не менее они должны находиться первыми в списке параметров.
Вызовем статический метод:
Да, это может вас удивить, но статические методы можно вызывать через объект класса. Вызов через точку нужен лишь для удобства. На самом же деле в случае статического метода никакие аргументы ( self или cls ) методу не передаются.
То есть статические методы не могут получить доступ к параметрам класса или объекта. Они работают только с теми данными, которые им передаются в качестве аргументов.
Теперь давайте вызовем те же самые методы, но на самом классе.
Метод класса и статический метод работают, как нужно. Однако вызов метода экземпляра класса выдаёт TypeError, так как метод не может получить на вход экземпляр класса.
Теперь, когда вы знаете разницу между тремя видами методов, давайте рассмотрим реальный пример для понимания того, когда и какой метод стоит использовать. Пример взят отсюда.
Когда использовать каждый из методов?
Выбор того, какой из методов использовать, может показаться достаточно сложным. Тем не менее с опытом этот выбор делать гораздо проще.
Чаще всего метод класса используется тогда, когда нужен генерирующий метод, возвращающий объект класса. Как видим, метод класса from_birth_year используется для создания объекта класса Person по году рождения, а не возрасту.
Статические методы в основном используются как вспомогательные функции и работают с данными, которые им передаются.