Декораторы Python используют понятие замыкание: объяснение здесь. Почитайте о замыканиях, чтобы попасть в декораторы.
Decorator принимает функцию, добавляет некоторую функциональность и возвращает ее.
Поэтому декораторы эффективно делают это:
Таким образом, если функция-декоратор не возвращает функцию, декоративная функция не может быть вызвана.
Теперь давайте познакомимся с концепцией замыкания при использовании в python:
То же самое достигается с помощью декораторов Python:
Одноразовое и постоянное украшение
Посмотрите эту реализацию, чтобы понять, что декораторы можно вызывать каждый раз с вызовом функции:
Прикованные декораторы
Это когда декораторы используются последовательно.
Обратите внимание, что здесь звездное украшение выполняется первым в первом определении и вторым во втором определении.
Примеры из реального мира
Когда есть несколько функций, которые почти похожи, но с небольшими изменениями в зависимости от регистра или входных данных, можно использовать декораторы для добавления дополнительных/изменяющихся функций, не пристегивая код. Это было бы в легкой отладке.
Другой пример - здесь декоратор рассчитывает время реализации функции.
*args и **kwargs
*args
позволяют использовать любое количество аргументов в функции. Это необходимо для объяснения многократного украшения
**kwargs
(аргументы с ключевыми словами) аналогичны *args, за исключением того, что это аргументы, для которых требуются ключевые слова.
передача формальных аргументов, *args и **kwargs:
Теперь давайте вернемся к примеру, в котором вычислялось время, необходимое для реализации функции. Эта функция должна быть универсальной с любым количеством аргументов с помощью some_function(*args,**kwargs)
.
Обратите внимание, что args
— это кортеж, который распаковывается в переменные с помощью *args
, а kwargs
— это словарь, который распаковывается с помощью **kwargs
. Подробнее читайте здесь: https://www.agiliq.com/blog/2012/06/understanding-args-and-kwargs/
Декораторы с аргументами
Условное оформление
Когда условие передается в декоратор
Альтернативное использование — это когда условие передается в саму функцию (кажется более реалистичным):
Дополнительные ресурсы для справки:
- http://www.siafoo.net/article/68 [Расширенные концепции декораторов]
- http://code.activestate.com/recipes/578222-a-python-decorator-that-re-executes-the-function-o/
- https://www.artima.com/weblogs/viewpost.jsp?thread=240845
Источники:
- https://medium.com/@rohanrony/code-better-with-python-closure-39e4b5f859d
- https://www.programiz.com/python-programming/decorator
- https://www.codementor.io/moyosore/a-dive-into-python-closures-and-decorators-part-1-9mpr98pgr
- https://www.codementor.io/moyosore/a-dive-into-python-closures-and-decorators-part-2-ab2enoyjg
- https://pythontips.com/2013/08/04/args-and-kwargs-in-python-explained/
- https://realpython.com/primer-on-python-decorators/
- https://www.thecodeship.com/patterns/guide-to-python-function-decorators/
- https://www.codeschool.com/blog/2016/05/12/a-guide-to-python-decorators/