Введение
В этом разделе представляется концепция декоратора. Это продвинутая тема, которую мы только коснемся поверхностно.
This tutorial is from open-source community. Access the source code
💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал
В этом разделе представляется концепция декоратора. Это продвинутая тема, которую мы только коснемся поверхностно.
Рассмотрим функцию.
def add(x, y):
return x + y
Теперь рассмотрим функцию с некоторым логированием добавленным к ней.
def add(x, y):
print('Calling add')
return x + y
Теперь вторая функция, также с некоторым логированием.
def sub(x, y):
print('Calling sub')
return x - y
Замечание: Это несколько повторяющееся.
Написание программ, где есть много повторяющегося кода, часто действительно раздражает. Они утомительно трудны для написания и сложны для поддержки. Особенно если вы решаете, что хотите изменить, как это работает (например, другой вид логирования).
Возможно, вы можете создать функцию, которая добавляет логирование к функциям. Обертку.
def logged(func):
def wrapper(*args, **kwargs):
print('Calling', func.__name__)
return func(*args, **kwargs)
return wrapper
Теперь используйте ее.
def add(x, y):
return x + y
logged_add = logged(add)
Что происходит, когда вы вызываете функцию, возвращаемую функцией logged
?
logged_add(3, 4) ## Вы видите, что появляется сообщение о логировании
Этот пример иллюстрирует процесс создания так называемой оберточной функции.
Обертка - это функция, которая оборачивает другую функцию с некоторыми дополнительными операциями обработки, но в противном случае работает точно так же, как и исходная функция.
>>> logged_add(3, 4)
Calling add ## Дополнительный вывод. Добавлен оберткой
7
>>>
Примечание: Функция logged()
создает обертку и возвращает ее в качестве результата.
Оборачивать функции в обертки - это чрезвычайно распространенная практика в Python. Такая распространенность привела к появлению специального синтаксиса для этого.
def add(x, y):
return x + y
add = logged(add)
## Особенный синтаксис
@logged
def add(x, y):
return x + y
Особенный синтаксис выполняет те же самые шаги, что и показано выше. Декоратор - это просто новый синтаксис. Говорят, что он декорирует функцию.
Есть много более тонких деталей по поводу декораторов, чем те, которые были представлены здесь. Например, использование их в классах. Или использование нескольких декораторов с функцией. Однако предыдущий пример хорошо иллюстрирует, как их использование обычно возникает. Обычно это в ответ на появление повторяющегося кода в широком спектре определений функций. Декоратор может перенести этот код в центральное определение.
Если вы определяете функцию, ее имя и модуль хранятся в атрибутах __name__
и __module__
. Например:
>>> def add(x,y):
return x+y
>>> add.__name__
'add'
>>> add.__module__
'__main__'
>>>
В файле timethis.py
напишите декораторную функцию timethis(func)
, которая оборачивает функцию дополнительным слоем логики, который выводит, сколько времени занимает выполнение функции. Для этого вы будете окружать функцию вызовами замера времени следующим образом:
start = time.time()
r = func(*args,**kwargs)
end = time.time()
print('%s.%s: %f' % (func.__module__, func.__name__, end-start))
Вот пример того, как должен работать ваш декоратор:
>>> from timethis import timethis
>>> @timethis
def countdown(n):
while n > 0:
n -= 1
>>> countdown(10000000)
__main__.countdown : 0.076562
>>>
Обсуждение: Этот декоратор @timethis
можно поместить перед любым определением функции. Таким образом, вы можете использовать его в качестве диагностического инструмента для настройки производительности.
Поздравляем! Вы завершили лабораторную работу по функциональным декораторам. Вы можете практиковаться в других лабораторных работах в LabEx, чтобы улучшить свои навыки.