Декораторы: покончим с вечной путаницей в декораторах и их использовании
Просматривая github или любую другую базу кода, мы часто сталкиваемся с чем-то, что не похоже на python.
@decorator
def my_function():
pass
Это известно как декоратор в python и является чрезвычайно удобным и мощным. Декоратор используется, когда нам нужно изменить поведение функции без изменения самой функции. Понятно? Теперь понятно.
Можно сказать, что почти все в python является объектом. Функции также являются объектами (первого класса). Поэтому мы можем присваивать функции переменной.
def my_function():
print("hello dev community")
#we can assign the function without executing to the variable func
func=my_function
Функции — это объекты первого класса
Они могут быть присвоены переменной, как было показано ранее.
Кроме того, их можно передавать в качестве аргумента другой функции, а также встраивать в другую функцию.
def outer(message):
def inner():
print("hi "+ message)
return inner
hi = outer("dev community")
bye = outer("dev community")
#this executes the inner function.
hi()
bye()
вывод
hi dev community
bye dev community
Здесь у нас есть две вложенные функции outer
и inner
.
Это называется замыканием. Закрытие позволяет избежать использования глобальных значений и обеспечивает некоторую форму сокрытия данных. Они также могут обеспечить объектно-ориентированное решение проблемы.
Декораторы широко используют замыкания
Вместо того чтобы принимать message
в качестве аргумента, декораторы принимают функции в качестве аргументов. Давайте создадим декоратор шаг за шагом.
def decorator_function(original_function):
def wrapper_function():
#do something before the function
print("hello from wrapper")
return original_function()
return wrapper_function
def display():
print("hello from display")
decor_display = decorator_function(display)
decor_display()
Код выглядит очень похоже на закрытие, которое мы создали ранее. Теперь мы передаем функцию через decorated_function
.
Когда мы присваиваем decor_display
, decorator_function
выполняется и возвращает wrapper_function
. Затем мы выполняем wrapper_function
, сохраненную в decor_display
, вызывая decor_display
в последней строке. Теперь wrapper_function
выполняет оператор печати, а original_function
, которая в нашем контексте является display
, выводит результат:
hello from wrapper
hello from display
Это было много для восприятия. Пройдитесь по процессу еще раз и, надеюсь, логика будет понятна.
Здесь нам успешно удалось изменить поведение функции display
, выведя перед ней дополнительную строку hello from wrapper
. Мы не изменяли саму функцию display
, а изменили ее поведение с помощью нашей функции decorator_function
.
Python позволяет нам сделать то же самое, используя @decorator_function_name
. Вместо того чтобы присваивать decorator_function
переменной, мы можем присвоить ее любой функции, используя @decorator_function
перед функцией.
def decorator_function(original_function):
def wrapper_function():
#do something before the function
print("hello from wrapper")
return original_function()
return wrapper_function
#this works same as decorator_function(display)
@decorator_function
def display():
print("hello from display")
display()
вывести
hello from wrapper
hello from display
Выводы
Декораторы являются мощным инструментом и используются во многих кодовых базах для различных целей, таких как логирование, тестирование производительности, кэширование, проверка прав доступа и т.д. Если вы нашли это руководство полезным, прокомментируйте его ниже. Спасибо за чтение и обучение.
декораторы часть II->