📝 Задания

⚡ Кратко

Задания закрепляют понимание декораторов: что делает functools.wraps, зачем *args, **kwargs, как задавать аргументы декоратору и как работает стекирование.

  • functools.wraps сохраняет имя и документацию.
  • *args, **kwargs нужны для совместимости с любыми аргументами.
  • Аргументы декоратору передаются через круглые скобки: @decorator(arg).

Вопросы для самопроверки

Вопрос 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, который при ошибке повторяет вызов заданное число раз с задержкой.

Проверка понимания

Выберите один вариант ответа. После клика правильный ответ подсветится зелёным.

Вопрос 1

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

Вопрос 2

Что делает yield?

Вопрос 3

Какой стиль имён переменных обычно рекомендует PEP 8?

Вопрос 4

Зачем использовать f-strings в современном Python?

Вопрос 5

Когда полезен ранний возврат из функции?

Вопрос 6

Что делает аннотация типа в Python?

Вопрос 7

Как лучше обрабатывать ожидаемую ошибку преобразования?