MiddleКодИногдаЕщё не отвечали
Декоратор, повторяющий вызов N раз и выводящий общее время
Напишите repeat(reps) — параметризованный декоратор, запускающий обёрнутую функцию reps раз, печатающий общее время и возвращающий результат последнего вызова.
Требования:
- Принимайте
repsкак аргумент декоратора:@repeat(3). - Пробрасывайте
*args/**kwargs; сохраняйте метаданные функции.
def repeat(reps):
# ваш код здесь
Допишите реализацию.
Нужны три уровня: repeat(reps) захватывает счётчик и возвращает декоратор; тот берёт func и возвращает обёртку с @wraps(func). Обёртка фиксирует time.perf_counter(), запускает func reps раз (сохраняя последний результат), печатает суммарное время и возвращает этот результат. Слой аргумента нужен для @repeat(3); @wraps сохраняет имя и докстринг.
- ✗Использовать два уровня и не принимать аргумент
repsкорректно - ✗Сбрасывать таймер внутри цикла вместо замера всего прогона
- ✗Опускать
@wraps, теряя имя и докстринг функции
- →Почему приём аргумента декоратора требует третьего уровня вложенности?
- →Что ломается для вызывающих, если опустить
@wrapsна обёртке?
Оглавление
Задача
Реализуйте repeat(reps): запустите функцию reps раз, выведите общее время и верните результат последнего вызова.
Решение
import time
from functools import wraps
def repeat(reps):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = None
for _ in range(reps):
result = func(*args, **kwargs)
print(f"{reps} repetitions in {time.perf_counter() - start} secs")
return result
return wrapper
return decorator
Ключевые моменты
- Три уровня: фабрика
repeat(reps)→ декораторdecorator(func)→wrapper. - Таймер запускается один раз вокруг всего цикла, а не внутри него.
@wraps(func)сохраняет имя и докстринг; результат — от последнего вызова.
Оглавление