description, author или version.  Для сохранения исходной сигнатуры декорируемой функции важно использовать functools.wraps. Пример:
  import functools
def add_metadata(description, author):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)
        wrapper.description = description
        wrapper.author = author
        return wrapper
    return decorator
@add_metadata(description="Функция для сложения двух чисел.", author="John Doe")
def add(x, y):
    return x + y
print(add.description)
print(add.author)
  Декораторы в Python позволяют элегантно добавлять метаданные к функциям, не изменяя их основной код. Метаданные могут быть полезны для документирования, introsкции, инструментов анализа кода, и для различных других целей.
Основная идея: Декоратор - это функция, которая принимает другую функцию в качестве аргумента, расширяет её функциональность и возвращает расширенную функцию. Мы можем использовать это, чтобы добавлять атрибуты к декорируемой функции.
Пример:
import functools
def add_metadata(metadata):
    def decorator(func):
        @functools.wraps(func) # Важно для сохранения исходной информации о функции
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)
        for key, value in metadata.items():
            setattr(wrapper, key, value)  # Добавляем метаданные как атрибуты
        return wrapper
    return decorator
@add_metadata({'description': 'Эта функция выполняет сложение.', 'author': 'AI Assistant'})
def add(x, y):
    """Складывает два числа."""
    return x + y
print(add.description)  # Выведет: Эта функция выполняет сложение.
print(add.author)      # Выведет: AI Assistant
print(add.__doc__)      # Выведет: Складывает два числа.
print(add.__name__)     # Выведет: add (благодаря functools.wraps)
Разъяснения:
add_metadata(metadata): Это наш декоратор, который принимает словарь metadata с парами ключ-значение, которые мы хотим добавить к функции.decorator(func): Эта вложенная функция принимает декорируемую функцию func.@functools.wraps(func): Ключевой момент!  Эта строка импортирует и использует functools.wraps, который гарантирует, что обертка wrapper сохраняет важную информацию об исходной функции func, такую как её __name__ (имя), __doc__ (строка документации),  и т.д.  Без этого декоратора, add.__name__ выведет "wrapper" вместо "add", что затруднит отладку и понимание кода.wrapper(*args, **kwargs):  Это функция-обертка, которая вызывает исходную функцию func с переданными аргументами.  Мы добавляем атрибуты *перед* возвратом этой обертки.  Если нужно как-то изменять поведение функции, это место, где это нужно делать.  В данном примере, мы просто вызываем исходную функцию без изменений.setattr(wrapper, key, value):  Мы перебираем пары ключ-значение в словаре metadata и используем setattr для добавления этих значений как атрибутов к обертке wrapper.return wrapper: Декоратор возвращает модифицированную функцию (в данном случае, обертку с добавленными атрибутами).@add_metadata(...): Синтаксис декоратора, который применяет декоратор add_metadata к функции add.Почему это важно?
Альтернативные подходы (менее предпочтительные):
func.__dict__.update(metadata) также работает, но setattr является более стандартным и читаемым способом.В заключение, использование декораторов с setattr и functools.wraps - это мощный и рекомендуемый способ добавления метаданных к функциям в Python, обеспечивающий чистый, поддерживаемый и гибкий код.