Декораторы в Python: руководство

Декораторы в Python: руководство Python

Декораторы — это мощный инструмент в языке программирования Python, который позволяет модифицировать поведение функций и классов без изменения их исходного кода. В этом уроке мы подробно рассмотрим, что такое декораторы, как они работают и как их использовать в своих проектах.

Бесплатный самоучитель Python

Что такое декораторы Python?

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

Простой пример декоратора:

def simple_decorator(func):
    def wrapper():
        print("Перед вызовом функции")
        func()
        print("После вызова функции")
    return wrapper

@simple_decorator
def say_hello():
    print("Привет!")

say_hello()

В этом примере simple_decorator — это декоратор, который оборачивает функцию say_hello. Когда мы вызываем say_hello(), на самом деле выполняется декорированная версия функции.

Как работают декораторы Python?

Когда мы используем синтаксис @decorator перед определением функции, Python автоматически передает эту функцию декоратору. Декоратор принимает эту функцию в качестве аргумента, создает новый объект-функцию (обычно называемый «wrapper» или «обертка») и возвращает его. Этот новый объект заменяет оригинальную функцию.

Декораторы, принимающие аргументы

Декораторы могут также принимать параметры. Давайте рассмотрим пример:

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(3)
def greet(name):
    print(f"Привет, {name}!")

greet("Алиса")

В этом примере декоратор repeat принимает аргумент times, который определяет, сколько раз будет вызвана декорируемая функция.

Применение декораторов Python

Декораторы имеют множество применений в Python. Вот несколько примеров использования декораторов:

1. Логирование:

import logging

def log_function_call(func):
    def wrapper(*args, **kwargs):
        logging.info(f"Вызвана функция {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@log_function_call
def add(a, b):
    return a + b

result = add(3, 5)
print(result)

2. Измерение времени выполнения:

import time

def measure_time(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:.2f} секунд")
        return result
    return wrapper

@measure_time
def slow_function():
    time.sleep(2)

slow_function()

3. Кэширование результатов:

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

@cache_result
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(100))

Декораторы классов

Декораторы могут также применяться к классам, позволяя изменять поведение классов. Вот пример:

def singleton(cls):
    instances = {}
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class Database:
    def __init__(self):
        print("Инициализация базы данных")

db1 = Database()
db2 = Database()
print(db1 is db2)  # Выведет: True

Использование functools.wraps

При создании декораторов важно сохранять метаданные декорируемой функции (такие как имя и документация). Для этого в стандартную библиотеку Python включен декоратор functools.wraps:

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        """Это документация обертки"""
        print("Перед выполнением")
        result = func(*args, **kwargs)
        print("После выполнения")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    """Это документация оригинальной функции"""
    print(f"Привет, {name}!")

say_hello("Мир")
print(say_hello.__name__)  # Выведет: say_hello
print(say_hello.__doc__)   # Выведет: Это документация оригинальной функции

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

Практикуйтесь в создании и использовании декораторов, и вы сможете писать более элегантный и эффективный код на Python. Помните, что возможности применения декораторов ограничены только вашим воображением!

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x