Сказка про декораторы в Python

от автора

image

Simple is better than complex.

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

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

Начнем.

Давным давно в большом, уютном проекте жила и трудилась функция fetch_webpage:

def fetch_webpage():     import requests     webpage = requests.get('https://google.com')     return webpage fetch_webpage()

Out:

<Response [200]>

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

def fetch_webpage():     import time      start = time.time()     import requests     webpage = requests.get('https://google.com')     end = time.time()     print('Время выполнения: {} секунд.'.format(end-start))     return webpage fetch_webpage()

Out:

Время выполнения: 0.1602182388305664 секунд. <Response [200]>

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

def wrapper(func):     import time     start = time.time()     out = func()     end = time.time()     print('Время выполнения: {} секунд.'.format(end-start))     return out  def fetch_webpage():     import requests     webpage = requests.get('https://google.com')     return webpage wrapper(fetch_webpage)

Out:

Время выполнения: 0.1602182388305664 секунд. <Response [200]>

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

def benchmark(func):     import time     def wrapper():         start = time.time()         func()         end = time.time()         print('Время выполнения: {} секунд.'.format(end-start))         return func()     return wrapper  @benchmark def fetch_webpage():     import requests     webpage = requests.get('https://google.com')     return webpage  fetch_webpage()

Out:

Время выполнения: 0.15940594673156738 секунд. <Response [200]>

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

ссылка на оригинал статьи https://habr.com/ru/post/524052/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *