Pull to refresh

Comments 38

По-моему, очень запутанные объяснения, в то время как декоратор является всего лишь синтаксическим сахаром для записи функции высшего порядка, преобразующей другую функцию:

@decorator
def f ()
  ...

буквально то же, что

def f ()
  ...
f = decorator(f)

Зачем в Питоне ввели отдельный синтаксис для этого частного случая, не очень понятно.

Спасибо за комментарий!
Вот раздел PEP с мотивацией добавления этого синтаксического сахара

Рассмотрели простейшие варианты использования декораторов;

Как только я открыл ссылку сразу увидел:

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

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

Спасибо за комментарий! Подберу релевантную статью к ссылке, не думал, что ошибусь именно там

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

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

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

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

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

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

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

Про вложенные декораторы я писал, что это "экзотический пример", и в большинстве случаев его использования стоит избегать. Но местами это может быть удобно в применении (хоть сложность поддерживания увеличивается). Опять же такая конструкция должна быть чем-то оправдана, что в виду ее сложности бывает редко

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

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

Интерфейсы создают точки роста, декораторы... я не знаю что создают.

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

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

Извините конечно меня, но с чего вы тогда взяли что это отличное место для декораторов? Ну и возможно еще чего-то из списка.

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

Я не могу гарантированно сказать, что применение декоратора в этом кейсе лучший вариант, так как это в равной мере зависит и от того, кто дает оценку и от того, какую цель мы преследуем (например написать быстро, качественно, или возможно нам нужна некоторая универсальность, возможно кто-то в принципе отказывается от написания классов, этого я знать не могу без контекста)

В том же djago, например есть возможность использовать вьюсеты как на базе классов, так и на базе функций, а fastapi по умолчанию работает с функциями

Декоратор вместо класса? Или декоратор вместо всей логики авторизации/аутентификации? И как понять более объемную логику? Вам в (или на декораторах, тут непонятно, если вы говорите что вложенные декораторы это плохо) декораторе точно так-же придется делать аутентификацию на какой-то реализации куки. Но по моему изначально класс под это намного лучше подходит в плане построения логики? Темболее в питоне есть прекраные магические методы, которые, получается, как декораторы, но над объектами.

Почитал пример декоратора с классами, вы приводите по сути реализацию гетера и сеттера на декораторах, он, если меня память не подводит, в С# вообще по умолчанию прописывается. Я к тому что декоратор в классах тоже выглядит лишним или избыточным.

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

Вот некоторые примеры
pydantic
django-rest-framework

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

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

Если вы предполагаете написание всей авторизации с нуля. Я как и вы крайне бы НЕ рекомендовал описывать всю логику в декораторе

Декоратор в большей мере необходим для удобства использования какого-то фрагмента кода, но никак не для хранилища всей кодовой базы какой-либо фичи

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

Вы имеете ввиду что просто вообще весь код постараетесь уместить в 1 функцию?

Если код занимает 10-15 строк, то почему бы и нет, в обратном случае стоит подумать, действительно ли этому коду тут место

Декоратор в большей мере необходим для удобства использования какого-то фрагмента кода

А наследование?

Вообще, я считаю, что в хорошей архитектуре ООП 70% кода пишется путем копировать - вставить, что-бы соблюсти архитектурный паттерн. И достигается это не наследованием, а интерфейсами.

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

Либо не использовать декораторы вообще. Я просто маленько упустил, погружаясь в материал, как мы ушли от "Декораторы отлично себя показывают в аторизации" к "Ну декораторы вот используется в библиотеках другими программистами" По ссылкам я просто вижу что они вызываются, что это должно сказать?)

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

Я не берусь, утверждать, что "декораторы отлично себя показывают в авторизации" но их присутствие например для проверки наличия прав у пользователя или проверки контекста запроса на то, является ли запрос анонимным или совершается авторизованным пользователем имеет место быть

Приведу некоторые примеры когда применение декораторов имеет смысл списком, чтобы не было необходимости проваливаться в статьи:

Оптимизация производительности функций (кэширование);

Тайминг и профилирование (измерение времени выполнения функции, проверки производительности);

Авторизация и аутентификация (проверки по типу login_required);

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

Не вижу противоречий между, "применение имеет смысл" из статьи и "имеет место быть" из комментария выше

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

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

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

Если это действительно важная тема требующая более детального рассмотрения, я с радостью освещу ее в одной из следующих статей

Тогда декоратор имеет место быть где угодно, не только в авторизации, зачем вообще этот список полезных мест?

Вы, по сути, можете реализовать декоратор, не только в питоне, он там идёт из коробки, но в других языках как-то обходятся без декоратора в авторизации, например. Или только в питоне такая особенность авторизации?)

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

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

И потому что это удобный синтаксический сахар, который улучшает читаемость кода

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

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

Как-то вы обошли пользу пространства имён декораторов в статье.

Я ссылался на статью про замыкание и в первом упоминании пространства имён я ссылаюсь на статью о нем. Возможно стоило раскрыть эту тему в одном из разделов статьи

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

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

И дальше вы выделяете именно авторизацию как успешный пример декораттра.

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

Никаких противопоказаний, а польза то какая? Так и не могу услышать. Я уверен, что смогу и без декораторов написать на питоне прекрасную авторизацию через ООП, а вы говорите что им самое место в авторизации, почему?

Если вы используете класс, методы которого реализуют логику многих эндпоинтов, вам удобнее указать для каждого метода тот набор проверок, который вам необходим, одной из них может быть проверка, что пользователь авторизован, на какой-то ручке вы хотите проверить, что пользователь авторизован и имеет ту или иную роль, где-то вы хотите проверить какое либо значение из cookie, в данном случае вам удобнее всего повесить нужный набор декораторов на нужные вам методы. Альтернативой является наследование от какого-то другого класса и указание например общей для всех эндпоинтов проверки авторизации, что может не подходить для решения задачи, либо вам нужно иметь какой-то атрибут с маппингом, проверок, которые нужны для того или иного метода, что является менее явным. Либо вы можете написать для каждого эндпоинта свой класс, что делать дольше.

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

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

Sign up to leave a comment.

Articles