Вопросы для самопроверки
Вопрос 1
Что делает functools.wraps?
- a. Удаляет лишние аргументы
- b. Автоматически вызывает декорируемую функцию
- c. Сохраняет имя и документацию исходной функции
Правильный ответ: c
Вопрос 2
Почему без functools.wraps теряется документация функции?
Ответ: потому что wrapper заменяет функцию, и метаданные не переносятся автоматически.
Вопрос 3
Для чего нужны *args и **kwargs в декораторах?
- a. Для совместимости с функциями без аргументов
- b. Для совместимости с функциями с любыми аргументами
- c. Для сокращения кода
Правильный ответ: b
Вопрос 4
Что делает следующий декоратор?
def custom_decorator(message: str):
def decorator(func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception:
print(message)
return wrapper
return decorator
Ответ: при возникновении ошибки выводит указанное сообщение.
Вопрос 5
Какая конструкция позволит задать аргументы декоратору?
- a.
@decor("info") - b.
@decor["info"] - c.
@decor = "info" - d.
@decor: "info"
Правильный ответ: a
Практические задания
Задание 1. Рамка-обводка
Создайте декоратор framed, который оборачивает результат в рамку из символов = длиной 40.
@framed
def show_title():
print("== Menu ==")
# Ожидаемый вывод:
# ========================================
# == Menu ==
# ========================================
Задание 2. Настраиваемая рамка-обводка
Доработайте декоратор framed, чтобы он принимал параметры width и symbol (по умолчанию "=").
@framed(30, "-")
def show_title():
print("== Menu ==")
# Ожидаемый вывод:
# ------------------------------
# == Menu ==
# ------------------------------
Задание 3. Декоратор upper
Создайте декоратор, который превращает возвращаемую строку в верхний регистр. Используйте functools.wraps.
Задание 4. Декоратор для повторных попыток
Напишите декоратор retry, который при ошибке повторяет вызов заданное число раз с задержкой.