python classmethod и staticmethod зачем нужны

Декораторы @classmethod и @staticmethod

Приветствую всех на внеочередном занятии по ООП. Меня часто спрашивают: чем отличаются обычные методы класса от методов, объявленных декораторами:

@classmethod и @staticmethod

Давайте разбираться. На уровне теории это выглядит так. Предположим, у нас есть класс Vector, который содержит два атрибута: MIN_COORD = 0, MAX_COORD = 100; обычный метод setCoords; метод уровня класса: validate и статический метод – norm2:

python classmethod и staticmethod зачем нужны. Смотреть фото python classmethod и staticmethod зачем нужны. Смотреть картинку python classmethod и staticmethod зачем нужны. Картинка про python classmethod и staticmethod зачем нужны. Фото python classmethod и staticmethod зачем нужны

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

Когда метод класса объявляется через декоратор @classmethod, то первым параметром ему нужно передать сам класс, а не его экземпляр. В результате, такой метод может обращаться ко всем свойствам и методам текущего класса Vector, но не к экземпляру (из, которого он может быть вызван).

Наконец, третий тип методов, объявленные через декоратор @staticmethod, являются, своего рода, совершенно изолированными и от свойств и методов класса и, уж тем более, от свойств и методов экземпляра. Их можно воспринимать как отдельные, самостоятельные функции, объявленные внутри класса. Обычно, это делают для удобства, т.к. их функционал так или иначе связан с тематикой класса.

Итак, давайте на практике посмотрим, что все это значит. Я объявлю класс Vector вот в таком виде:

И для удобства открою консоль Python, где импортирую этот класс из модуля ex1:

Далее, смотрите, непосредственно через класс Vector можно вызвать метод класса:

Источник

Python’s @classmethod и @staticmethod Объяснили

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

Декоратор @classmethod

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

В этих методах экземпляра аргумент self является самим объектом экземпляра класса, который затем может быть использован для действия с данными экземпляра. @classmethod методы также имеют обязательный первый аргумент, но этот аргумент не является экземпляром класса, на самом деле это сам деинсталлированный класс. Таким образом, в то время как типичный метод класса может выглядеть следующим образом:

Вместо этого будет использоваться аналогичный метод @classmethod :

Приведенный выше пример очень прост, но вы можете представить себе более сложные примеры, которые делают его более привлекательным. Представьте себе, что объект Student может быть сериализован во множество различных форматов. Вы можете использовать эту же стратегию, чтобы разобрать их все:

Декоратор становится еще более полезным, когда вы осознаете его полезность в подклассах. Поскольку объект класса дается вам внутри метода, вы все равно можете использовать тот же @classmethod и для подклассов.

Декоратор @staticmethod

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

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

@classmethod vs @staticmethod

Самое очевидное между этими декораторами-их способность создавать статические методы внутри класса. Эти типы методов могут быть вызваны на деинсталлированных объектах класса, так же как классы, использующие ключевое слово static в Java.

Этот параметр cls является объектом класса, о котором мы говорили, что позволяет методам @classmethod легко создавать экземпляры класса, независимо от какого-либо наследования. Отсутствие этого параметра cls в методах @staticmethod делает их истинными статическими методами в традиционном смысле. Их основная цель состоит в том, чтобы содержать логику, относящуюся к классу, но эта логика не должна иметь никакой потребности в конкретных данных экземпляра класса.

Более Длинный Пример

Теперь давайте рассмотрим другой пример, где мы используем оба типа вместе в одном классе:

Вывод

В этой статье вы видели, как оба декоратора @classmethod и @staticmethod работают в Python, некоторые примеры каждого из них в действии и как они отличаются друг от друга. Надеюсь, теперь вы можете применить их к своим собственным проектам и использовать их для дальнейшего улучшения качества и организации вашего собственного кода.

Вы когда-нибудь использовали эти декораторы раньше, и если да, то как? Дайте нам знать в комментариях!

Источник

Значение @classmethod и @staticmethod для начинающих?

может кто-нибудь объяснить мне значение @classmethod и @staticmethod в python? Мне нужно знать разницу и смысл.

насколько я понимаю, @classmethod сообщает классу, что это метод, который должен быть унаследован в подклассы или. что-то. Но какой в этом смысл? Почему бы просто не определить метод класса без добавления @classmethod или @staticmethod и @ определения?

tl; dr: , когда должен ли я использовать их,почему должен ли я использовать их, и как должен ли я использовать их?

Я довольно продвинутый с C++, поэтому использование более продвинутых концепций программирования не должно быть проблемой. Не стесняйтесь давать мне соответствующий пример c++, если это возможно.

11 ответов

хотя classmethod и staticmethod очень похожи, есть небольшая разница в использовании для обеих сущностей: classmethod должен иметь ссылку на объект класса в качестве первого параметра, в то время как staticmethod не может иметь параметров.

пример

объяснение

предположим пример класса, занимающегося информацией о дате (это будет наш шаблон):

этот класс, очевидно, может использоваться для хранения информация об определенных датах (без информации о часовом поясе; предположим, что все даты представлены в формате UTC).

Метод Класса

у нас есть некоторые задачи, которые можно красиво сделать с помощью classmethod s.

предположим, что мы хотим создать большое Date экземпляры класса, имеющие информацию о дате, поступающую из внешнего источника, закодированного в виде строки с форматом ‘dd-mm-yyyy’. Предположим, мы должны сделать это в разных местах исходного кода нашего проекта.

Итак, что мы должны сделать вот это:

это будет выглядеть так:

давайте более внимательно рассмотрим вышеуказанную реализацию и рассмотрим, какие преимущества у нас есть здесь:

статический метод

давайте посмотрим на следующий вариант использования.

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

где staticmethod может быть полезно. Давайте посмотрим на следующий фрагмент кода:

ответ Ростислава Дзинко очень уместен. Я думал, что могу выделить еще одну причину, по которой вы должны выбрать @classmethod над @staticmethod при создании дополнительного конструктора.

в приведенном выше примере, Ростислав используется @classmethod from_string как фабрика для создания Date объекты из других неприемлемых параметров. То же самое можно сделать с @staticmethod как показано в коде ниже:

и new_year и millenium_new_year несколько экземпляров Date класса.

но, если вы внимательно наблюдаете, Заводской процесс жестко закодирован для создания Date объекты независимо от того, что. Это означает, что даже если Date класс подклассов, подклассы по-прежнему будут создавать простые Date object (без какого-либо свойства подкласса). См. это в примере ниже:

в большинстве случаев, это нежелательно. Если вам нужен Заводской метод, который знает класс, который его вызвал, то @classmethod это то, что вам нужно.

переписывание Date.millenium as (это единственная часть вышеуказанного кода, которая изменяется)

причина в том, как вы знаете в настоящее время, @classmethod вместо @staticmethod

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

@staticmethod означает: когда этот метод вызывается, мы не передаем экземпляр класса (как мы обычно делаем с методами). Это означает, что вы можете поместить функцию внутри класса, но не можете получить доступ к экземпляру этот класс (это полезно, когда ваш метод не использует экземпляр).

когда использовать каждый

@staticmethod функция-это не что иное, как функция, определенная внутри класса. Он вызывается без создания экземпляра класса first. Это определение неизменяемо через наследование.

здесь хорошая ссылка на эту тему.

можно было бы использовать @classmethod когда он / она захочет изменить поведение метода, на основе которого подкласс вызывает метод. помните, что у нас есть ссылка на вызывающий класс в методе class.

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

небольшая компиляция

@staticmethod Способ записи метода внутри класса без ссылки на вызываемый объект. Поэтому нет необходимости передавать неявный аргумент, такой как self или cls. Он написан точно так же, как написано вне класса, но он не бесполезен в python, потому что, если вам нужно инкапсулировать метод внутри класса, так как этот метод должен быть частью этого класса @staticmethod пригодится в это дело.

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

сравнение между этими двумя методами может быть ниже

python classmethod и staticmethod зачем нужны. Смотреть фото python classmethod и staticmethod зачем нужны. Смотреть картинку python classmethod и staticmethod зачем нужны. Картинка про python classmethod и staticmethod зачем нужны. Фото python classmethod и staticmethod зачем нужны

когда я должен их использовать, почему я должен их использовать и как я должен их использовать?

не нужно либо декоратор. Но по принципу, что вы должны минимизировать количество аргументов для функций (см. Clean Coder), они полезны именно для этого.

для обоих методов экземпляра и методы класса, не принимающие хотя бы один аргумент, являются TypeError, но не понимающие семантику этого аргумента-это ошибка пользователя.

(определение some_function ‘s, например:

и это будет работать.)

пунктирные поиски на экземплярах и классах:

Примечание, пунктирный поиск в экземпляре вызывается следующим образом:

и методы вызываются атрибуты:

методы экземпляра

необходимо получить доступ к методам экземпляра из экземпляров класс.

методы класса

вы можете получить доступ к этому методу через экземпляр класса (или подкласса).

статические методы

никакие аргументы не указаны неявно. Этот метод работает как любая функция, определенная (например) в пространстве имен модулей, за исключением того, что ее можно найти

опять же, когда я должен использовать зачем мне их использовать?

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

используйте их, когда вам не нужна информация.

это делает ваши функции и методы легче рассуждать и unittest.

функции с меньше аргументов легче рассуждать. Они также легче unittest.

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

примеры строение

вот несколько моих любимых примеров сборки:

на str.maketrans статический метод был функцией в string модуль, но гораздо более удобным для него, чтобы быть доступным от str пространство имен.

на dict.fromkeys метод class возвращает новый словарь, созданный из iterable ключей:

когда подкласс, мы видим, что он получает информацию о классе как метод класса, что очень полезно:

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

используйте методы класса, когда вам не нужна информация об экземпляре, но вам нужна информация о классе, возможно, для другого класса или статических методов или, возможно, для самого конструктора. (Вы не будете жестко кодировать класс, чтобы подклассы могли использоваться здесь.)

Я новичок на этом сайте, я прочитал все ответы выше, и получил информацию, что я хочу. Однако я не имею права голосовать. Поэтому я хочу начать с StackOverflow с ответа, как я его понимаю.

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

короче говоря, @classmehtod превращает обычный метод в заводской метод.

давайте рассмотрим его на примере:

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

как например с @classmethod

Class метод может изменить состояние класса, он привязан к классу и содержит cls в качестве параметра.

статический метод не может изменить состояние класса, он привязан к классу и не знает class или instance

Источник

Python: статические методы, методы класса и экземпляра класса

python classmethod и staticmethod зачем нужны. Смотреть фото python classmethod и staticmethod зачем нужны. Смотреть картинку python classmethod и staticmethod зачем нужны. Картинка про python classmethod и staticmethod зачем нужны. Фото python classmethod и staticmethod зачем нужны

Aug 1, 2019 · 4 min read

python classmethod и staticmethod зачем нужны. Смотреть фото python classmethod и staticmethod зачем нужны. Смотреть картинку python classmethod и staticmethod зачем нужны. Картинка про python classmethod и staticmethod зачем нужны. Фото python classmethod и staticmethod зачем нужны

Согласно модели данных Python, язык предлагает три вида методов: статические, класса и экземпляра класса. Давайте посмотрим, что же происходит за кулисами каждого из видов методов. Понимание принципов их работы поможет в создании красивого и эффективного кода. Начнём с самого простого примера, в котором демонстрируются все три вида методов.

Методы экземпляра класса

Это наиболее часто используемый вид методов. Методы экземпляра класса принимают объект класса как первый аргумент, который принято называть self и который указывает на сам экземпляр. Количество параметров метода не ограничено.

Встроенный пример метода экземпляра — str.upper() :

Методы класса

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

Встроенный пример метода класса — dict.fromkeys() — возвращает новый словарь с переданными элементами в качестве ключей.

Статические методы

Их можно воспринимать как методы, которые “не знают, к какому классу относятся”.

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

С теорией достаточно. Давайте разберёмся с работой методов, создав объект нашего класса и вызвав поочерёдно каждый из методов: instancemethod, classmethod and staticmethod.

Теперь давайте вызовем метод класса:

Мы видим, что метод класса classmethod() имеет доступ к самому классу ToyClass, но не к его конкретному экземпляру объекта. Запомните, в Python всё является объектом. Класс тоже объект, который мы можем передать функции в качестве аргумента.

Заметьте, что self и cls — не обязательные названия и эти параметры можно называть иначе.

Это лишь общепринятые обозначения, которым следуют все. Тем не менее они должны находиться первыми в списке параметров.

Вызовем статический метод:

Да, это может вас удивить, но статические методы можно вызывать через объект класса. Вызов через точку нужен лишь для удобства. На самом же деле в случае статического метода никакие аргументы ( self или cls ) методу не передаются.

То есть статические методы не могут получить доступ к параметрам класса или объекта. Они работают только с теми данными, которые им передаются в качестве аргументов.

Теперь давайте вызовем те же самые методы, но на самом классе.

Метод класса и статический метод работают, как нужно. Однако вызов метода экземпляра класса выдаёт TypeError, так как метод не может получить на вход экземпляр класса.

Теперь, когда вы знаете разницу между тремя видами методов, давайте рассмотрим реальный пример для понимания того, когда и какой метод стоит использовать. Пример взят отсюда.

Когда использовать каждый из методов?

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

Чаще всего метод класса используется тогда, когда нужен генерирующий метод, возвращающий объект класса. Как видим, метод класса from_birth_year используется для создания объекта класса Person по году рождения, а не возрасту.

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

Источник

Объяснение @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 или обычной функции.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *