Как в Python вернуть функцию из другой функции?

Ответ

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

Эта возможность лежит в основе таких мощных концепций, как замыкания и декораторы.

Пример: Фабрика функций

def create_multiplier(factor):
    """Эта функция создает и возвращает новую функцию."""
    def multiplier(number):
        """Эта функция умножает свой аргумент на 'захваченный' factor."""
        return number * factor

    return multiplier

# Создаем функцию, которая будет умножать на 2
double = create_multiplier(2)

# Создаем функцию, которая будет умножать на 3
triple = create_multiplier(3)

print(f"Double 5: {double(5)}")  # Вывод: Double 5: 10
print(f"Triple 5: {triple(5)}")  # Вывод: Triple 5: 15

Почему это работает?

Внутренняя функция multiplier "захватывает" переменную factor из своего внешнего лексического окружения. Этот механизм называется замыканием (closure). Даже после того, как create_multiplier завершила свою работу, возвращенная функция multiplier все еще помнит значение factor, с которым она была создана.

Ответ 18+ 🔞

А, ну ты смотри, какие штуки в Python есть! Функции там — это объекты первого класса, блядь. То есть с ними можно делать всё то же самое, что и с обычными переменными: в переменную запихнуть, другой функции в аргументы сунуть, или вообще вернуть как результат. Пиздец, да?

Вот на этой ебаной магии и держатся замыкания с декораторами, которые мозг выносят, если честно.

Смотри, как завод по производству функций устроен

def create_multiplier(factor):
    """Эта функция создает и возвращает новую функцию."""
    def multiplier(number):
        """Эта функция умножает свой аргумент на 'захваченный' factor."""
        return number * factor

    return multiplier

# Создаем функцию, которая будет умножать на 2
double = create_multiplier(2)

# Создаем функцию, которая будет умножать на 3
triple = create_multiplier(3)

print(f"Double 5: {double(5)}")  # Вывод: Double 5: 10
print(f"Triple 5: {triple(5)}")  # Вывод: Triple 5: 15

А какого хуя это вообще работает-то?

А вот тут, сука, самое интересное! Внутренняя функция multiplier — она ж хитрая жопа, она хватает переменную factor из внешней области видимости и не отпускает. Это и есть замыкание (closure), ёпта. Даже когда create_multiplier уже давно кончилась и забылась, её дочка multiplier всё помнит, с каким factor её родили. Вот так вот, в рот меня чих-пых, память у неё отличная!