Декораторы - это мощный инструмент в Python, позволяющий добавлять функциональность к существующим функциям (или классам) без изменения их кода. Они особенно полезны для добавления логирования, поскольку позволяют централизованно управлять логикой логирования и применять ее к множеству функций.
Вот как декораторы могут быть полезны для добавления логирования:
@log_function.  Чтобы удалить логирование, достаточно удалить эту строку.  Это очень удобно для отладки и мониторинга.
    Пример:
import logging
import functools
logging.basicConfig(level=logging.INFO)
def log_function(func):
  @functools.wraps(func)
  def wrapper(*args, **kwargs):
    logging.info(f"Вызвана функция: {func.__name__} с аргументами: {args}, {kwargs}")
    try:
      result = func(*args, **kwargs)
      logging.info(f"Функция {func.__name__} вернула: {result}")
      return result
    except Exception as e:
      logging.error(f"В функции {func.__name__} произошла ошибка: {e}")
      raise  # Перевыбрасываем исключение, чтобы не скрывать ошибку
  return wrapper
@log_function
def add(x, y):
  return x + y
@log_function
def divide(x, y):
  return x / y
add(5, 3)
try:
    divide(10, 0)
except Exception as e:
    pass # Обработка исключения в вызывающем коде
В этом примере декоратор log_function оборачивает функции add и divide, добавляя логирование при их вызове и возврате значений (или возникновении ошибок).  Обратите внимание на использование @functools.wraps(func) для сохранения метаданных декорируемой функции (имя, docstring и т.д.). Это важно для правильной работы introspection и отладки.
Таким образом, декораторы предоставляют элегантный и эффективный способ добавления логирования в Python, обеспечивая чистоту кода, уменьшение дублирования и гибкость настройки.