Как декоратор может изменить значение, возвращаемое функцией?

Декоратор может изменять возвращаемое значение функции, обернув её в другую функцию. Эта "обертка" получает результат работы исходной функции и может модифицировать его (преобразовать, дополнить, заменить) перед тем, как вернуть новое значение. Например:

  def decorator(func):
    def wrapper(*args, **kwargs):
      result = func(*args, **kwargs)
      modified_result = result + 1 # Пример изменения
      return modified_result
    return wrapper

  @decorator
  def my_function(x):
    return x

  print(my_function(5)) # Выведет 6
  

Декоратор в Python — это функция, которая принимает другую функцию в качестве аргумента, добавляет к ней некую функциональность и возвращает новую функцию. Декоратор может изменить возвращаемое значение исходной функции, "обернув" ее результат в дополнительные операции.

Вот как это работает:

  1. Декоратор получает исходную функцию как аргумент.
  2. Внутри декоратора определяется новая функция (часто называемая "wrapper" или "inner").
  3. Эта "внутренняя" функция вызывает исходную функцию.
  4. Ключевой момент: Вместо того, чтобы просто вернуть результат, полученный от исходной функции, "внутренняя" функция может этот результат обработать. Например, изменить его тип, округлить число, добавить текст, использовать как аргумент для другой функции, или даже вернуть совершенно другое значение, игнорируя оригинальный результат.
  5. Декоратор возвращает эту "внутреннюю" функцию.

Когда мы "декорируем" функцию, мы, по сути, заменяем исходную функцию новой функцией, возвращенной декоратором. Поэтому, когда вызывается "декорированная" функция, на самом деле вызывается "внутренняя" функция декоратора, которая может изменять или полностью заменять возвращаемое значение.

Пример:


def умножить_на_два(func):
    def wrapper(*args, **kwargs):
        результат = func(*args, **kwargs)
        return результат * 2  # Изменение возвращаемого значения
    return wrapper

@умножить_на_два
def вернуть_число(x):
    return x

print(вернуть_число(5))  # Выведет 10
    

В этом примере:

  • умножить_на_два - это декоратор.
  • вернуть_число - это исходная функция.
  • Декоратор оборачивает вернуть_число в функцию wrapper.
  • wrapper вызывает вернуть_число, получает результат, умножает его на 2 и возвращает удвоенное значение.

Таким образом, декоратор изменяет значение, возвращаемое функцией вернуть_число.

Другой пример, где декоратор может вернуть совершенно другое значение, если исходная функция вернула None:


def верни_default_если_none(default_value):
    def decorator(func):
        def wrapper(*args, **kwargs):
            result = func(*args, **kwargs)
            if result is None:
                return default_value
            return result
        return wrapper
    return decorator

@верни_default_если_none("Значение по умолчанию")
def может_вернуть_none():
    # Какая-то логика, которая иногда возвращает None
    return None

print(может_вернуть_none()) # Выведет "Значение по умолчанию"
    

Этот пример демонстрирует, как декоратор может кардинально изменить возвращаемое значение, в зависимости от логики, реализованной внутри "внутренней" функции декоратора.

0