⚖️ Старый подход vs современный Python

⚡ Кратко

Исходный материал уже использует современный синтаксис @ и functools.wraps. Главные улучшения — добавить type hints, использовать time.perf_counter() вместо time.time() и применять guard clauses.

  • time.perf_counter() точнее time.time() для замеров.
  • Type hints делают сигнатуры декораторов понятнее.
  • Guard clauses упрощают вложенность в retry.

Сравнение подходов

АспектПодход из источникаСовременная практика
Замер времени time.time() time.perf_counter() — точнее для коротких интервалов
Метаданные Использует functools.wraps Добавлять @functools.wraps ко всем ручным декораторам
Аргументы *args, **kwargs То же + аннотации типов на фабриках
Ретрай except Exception as e + time.sleep(5) Guard clauses, настраиваемый delay, логирование попыток
Стиль Базовый PEP 8 PEP 8 + type hints + f-strings + ранний возврат

Пример: retry в современном стиле

import time
import functools


def retry(attempts: int, delay: float = 1.0):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(1, attempts + 1):
                try:
                    return func(*args, **kwargs)
                except Exception as exc:
                    print(f"Attempt {attempt} failed: {exc}")
                    if attempt == attempts:
                        print("All attempts exhausted.")
                        return None
                    time.sleep(delay)
            return None  # unreachable, but makes return path explicit
        return wrapper
    return decorator

Когда ничего не устарело

Исходный материал не содержит устаревших конструкций: синтаксис @decorator, *args/**kwargs, functools.wraps и фабрики декораторов остаются актуальными. Современные проекты дополняют их type hints, более точными таймерами и явной обработкой ошибок.

Проверить по документации: рекомендации по замерам времени — в документации time.perf_counter.