Как часто следует использовать декораторы Python?
Вопрос
Недавно я начал экспериментировать с декораторами Python (и функциями более высокого порядка), потому что казалось, что они могли бы сделать мои модульные тесты Django более краткими.например, вместо того, чтобы писать:
def visit1():
login()
do_stuff()
logout()
Я мог бы вместо этого сделать
@handle_login
def visit1():
do_stuff()
Однако после некоторых экспериментов я обнаружил, что декораторы не так просты, как я надеялся.Сначала меня смутил различный синтаксис декоратора, который я нашел в разных примерах, пока я не узнал, что декораторы ведут себя совсем по-разному, когда они принимать аргументы.Затем я попробовал украсить метод и в конце концов узнал, что он не работает, потому что сначала я должен превратите мой декоратор в дескриптор путем добавления __get__
способ.В течение всего этого процесса я несколько раз запутывался и все еще нахожу, что отладка этого "оформленного" кода сложнее, чем обычно для Python.Сейчас я переоцениваю, действительно ли мне нужны декораторы в моем коде, поскольку моей первоначальной мотивацией было немного сэкономить при наборе текста, а не потому, что было что-то, что действительно требовало функций более высокого порядка.
Итак, мой вопрос заключается в следующем:следует ли использовать декораторы щедро или экономно?Становится ли еще более питоническим избегать их использования?
Решение
Декораторы прекрасны на своем месте, и их определенно не следует избегать - когда это уместно;-).Я вижу, что ваш вопрос по сути означает "Хорошо, итак, когда являются они подходят"?
Хорошим примером является добавление некоторого префиксного и / или постфиксного кода вокруг некоторых, но не всех методов некоторых классов.Были ли это все методы, а класс декоратор для обертывания всех методов был бы лучше, чем повторение @thisonetoo
бесконечно;-).Если это происходит один раз в blue moon, то не стоит прибегать к рефакторингу с использованием оберток (декораторов или чего-то другого).В центре есть большая площадка, где декораторы действительно вполне подходят.
Это сводится к одному из золотых правил программирования - DRY, ибо не повторяйся.Когда вы видите, что ваш код становится повторяющимся, вам следует реорганизовать повторение - и декораторы являются отличным инструментом для этого, хотя они далеко не единственные (вспомогательные методы и функции, пользовательские метаклассы, генераторы и другие итераторы, контекстные менеджеры... многие из функций, которые мы добавили в Python за последние несколько лет, лучше всего можно рассматривать как вспомогательные средства, более простые и плавные способы исключить ту или иную частую форму повторения!).
Если нет повторений, нет реальной необходимости в рефакторинге, следовательно (в частности) нет реальной необходимости в декораторах - в таких случаях YAGNI (вам это не понадобится) может превзойти DRY ;-).
Другие советы
Алекс уже довольно хорошо ответил на ваш вопрос, что я бы добавил, так это декораторы, которые делают ваш код НАМНОГО проще для понимания.(Иногда, даже если вы делаете это только один раз).
Например, изначально я пишу свои представления Django, вообще не думая об авторизации.И когда я закончу их писать, я смогу увидеть, какие из них нуждаются в авторизованных пользователях, и просто поставлю для них @login_required.
Так что любой, кто придет после меня, может с одного взгляда увидеть, какие виды защищены авторизацией.
И, конечно, они гораздо более СУХИЕ и кладут это повсюду.
если нет, запросите.user.is_authenticated():возвращает HttpResponseREdiect(..)
Декораторы - это способ поднять общий Аспект из вашего кода.
Аспектно-ориентированное программирование сторонники скажут вам, что существует так много общих аспектов, что AOP является важным и центральным.Действительно, вы можете прочитать глупую дискуссию на эту тему здесь:
Аспектно - ориентированное программирование противОбъектно-ориентированное программирование
Существует несколько распространенных вариантов использования AOP.Вы можете прочитать некоторые из них здесь:
Есть несколько сквозных проблем, в решении которых декораторы могут быть полезны.
Контроль доступа ("безопасность") Аутентификация, авторизация, разрешения, право собственности
Ведение журнала (включая средства отладки и аудита)
Кэширование (часто реализация Запоминание)
Некоторая обработка ошибок может быть распространенным аспектом и, следовательно, подходить для реализации декоратора.
Существует очень мало других шаблонов дизайна, которые действительно являются сквозными и заслуживают AOP decorator.
Если у вас один и тот же код в начале и в конце многих функций, я думаю, это оправдало бы дополнительную сложность использования декоратора.
Это скорее похоже на использование красивого (но, возможно, сложного) шаблона для веб-сайта с большим количеством страниц, это действительно экономит время и в конечном итоге добавляет ясности.