Сообщить об ошибке.

Практические примеры применения декоратора Python

В материале представлены несколько полезных декораторов, часто используемые программистами.

Оптимизации производительности функций

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

def cache(func):
    cache = {}

    def wrapper(*args):
        if args in cache:
            return cache[args]
        else:
            result = func(*args)
            cache[args] = result
            return result

    return wrapper

@cache
def fib(n):
    if n in (0, 1):
        return n
    return fib(n-1) + fib(n-2)

print(fib(40))  
# 102334155

Тайминг и профилирование

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

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"Функция {func.__name__} выполняется за {end_time - start_time:.6f} секунд")
        return result
    return wrapper

@timer
def my_function():
    # код функции

my_function()

Авторизация и аутентификация

Декораторы можно использовать для реализации авторизации и аутентификации в веб-приложениях. Например, для проверки того, вошел ли пользователь в систему, прежде чем разрешить ему доступ к определенным страницам.

Этот код предназначен для веб-приложения Flask, у которого есть защищенная страница под названием /dashboard.

from flask import Flask, request, redirect, url_for, session

app = Flask(__name__)

# Определяем декоратор
def login_required(func):
    def wrapper(*args, **kwargs):
        # Проверяем присутствие ключа 'username' в сеансе
        if 'username' in session:
            # Если есть, то вызываем исходную функцию
            return func(*args, **kwargs)
        else:
            # Если нет, то переадресуем пользователя на страницу входа.
            return redirect(url_for('login', next=request.url))
    return wrapper

@app.route('/dashboard')
@login_required
def dashboard():
    # Этот код будет выполнен только в том случае, 
    # если пользователь вошел в систему
    return "Это защищенная страница"

Логирование аргументов функции

Декораторы можно использовать для реализации журналирования аргументов функции. Может быть полезно для отладки и мониторинга поведения функции.

import logging

def log(func):
    logging.basicConfig(level=logging.DEBUG)

    def wrapper(*args, **kwargs):
        if args and not kwargs:
            logging.debug(f"Функции {func.__name__} переданы `args`: {args}")
        elif kwargs and not args:
            logging.debug(f"Функции {func.__name__} переданы `kwargs`: {kwargs}")
        elif kwargs and args:
            logging.debug(f"Функции {func.__name__} переданы `args`: {args} и `kwargs`: {kwargs}")
        return func(*args, **kwargs)

    return wrapper

@log
def my_function(a, b):
    # код функции

my_function()

Обработка ошибок

Декораторы можно использовать для реализации обработки ошибок в функциях Python. Может быть полезно для последовательной и структурированной обработки исключений.

def error_handle(func):
    def wrapper(*args, **kwargs):
        result = None
        try:
            result = func(*args, **kwargs)
        except Exception as e:
            print(f"Произошла ошибка в функции {func.__name__}: {e}")

        return result
    return wrapper

@error_handle
def my_function():
    # код функции

my_function()