← Назад к вопросам

Можно ли вернуть из функции функцию?

1.0 Junior🔥 191 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Можно ли вернуть из функции функцию?

Да, абсолютно можно! В Python функции — это объекты первого класса (first-class objects), поэтому их можно возвращать из других функций, передавать как аргументы и присваивать переменным. Это один из мощных аспектов функционального программирования.

Основной принцип

Функции в Python — это объекты, как любые другие:

def greet():
    return 'Hello'

# Функция как объект
print(greet)  # <function greet at 0x...>
print(type(greet))  # <class 'function'>

# Присваивание функции переменной
say_hello = greet
print(say_hello())  # Hello

# Функция может возвращать функцию
def get_greeter():
    return greet

greeter = get_greeter()
print(greeter())  # Hello

Возврат функции из функции

Пример 1: Простой возврат функции

def make_adder(n):
    """Возвращает функцию, которая добавляет n к аргументу"""
    def add(x):
        return x + n
    return add  # Возвращаем саму функцию, не результат её вызова

add_5 = make_adder(5)
add_10 = make_adder(10)

print(add_5(3))   # 8 (3 + 5)
print(add_10(3))  # 13 (3 + 10)

Пример 2: Замыкание (closure)

Возвращённая функция может использовать переменные внешней функции:

def create_multiplier(n):
    """Создаёт функцию, которая умножает на n"""
    def multiply(x):
        return x * n
    return multiply

multiply_by_2 = create_multiplier(2)
multiply_by_3 = create_multiplier(3)

print(multiply_by_2(5))  # 10
print(multiply_by_3(5))  # 15

# Замыкание сохранило значение n
print(multiply_by_2.__closure__)  # (<cell at ...: int object at ...>,)
print(multiply_by_2.__closure__[0].cell_contents)  # 2

Пример 3: Декоратор (частный случай)

Декораторы — это функции, возвращающие функции:

def my_decorator(func):
    """Декоратор, оборачивающий функцию"""
    def wrapper(*args, **kwargs):
        print(f'Вызов функции {func.__name__}')
        result = func(*args, **kwargs)
        print(f'Функция завершена')
        return result
    return wrapper

@my_decorator
def say_hello(name):
    return f'Hello, {name}!'

print(say_hello('Alice'))
# Вывод:
# Вызов функции say_hello
# Hello, Alice!
# Функция завершена

Практические примеры

Пример 4: Фабрика функций (function factory)

def create_greeting(greeting_text):
    """Фабрика функций приветствия"""
    def greet(name):
        return f'{greeting_text}, {name}!'
    return greet

english_greet = create_greeting('Hello')
french_greet = create_greeting('Bonjour')
russian_greet = create_greeting('Привет')

print(english_greet('Alice'))   # Hello, Alice!
print(french_greet('Bob'))      # Bonjour, Bob!
print(russian_greet('Charlie')) # Привет, Charlie!

Пример 5: Возврат разных функций в зависимости от условия

def get_operation(op_type):
    """Возвращает функцию операции в зависимости от типа"""
    def add(a, b):
        return a + b
    
    def subtract(a, b):
        return a - b
    
    def multiply(a, b):
        return a * b
    
    operations = {
        'add': add,
        'subtract': subtract,
        'multiply': multiply
    }
    
    return operations.get(op_type, lambda a, b: None)

add_func = get_operation('add')
multiply_func = get_operation('multiply')

print(add_func(5, 3))       # 8
print(multiply_func(5, 3))  # 15

Пример 6: Кэширование с помощью замыкания

def create_cache():
    """Создаёт функцию с встроенным кэшем"""
    cache = {}
    
    def fibonacci(n):
        if n in cache:
            print(f'Из кэша: {n}')
            return cache[n]
        
        if n < 2:
            result = n
        else:
            result = fibonacci(n - 1) + fibonacci(n - 2)
        
        cache[n] = result
        return result
    
    return fibonacci

fib = create_cache()
print(fib(10))  # 55, кэш сохранил промежуточные значения

Пример 7: Логирование операций

def create_logger(prefix):
    """Возвращает функцию-логгер с определённым префиксом"""
    def log(message):
        return f'[{prefix}] {message}'
    return log

error_log = create_logger('ERROR')
info_log = create_logger('INFO')
warning_log = create_logger('WARNING')

print(error_log('Connection failed'))  # [ERROR] Connection failed
print(info_log('Server started'))      # [INFO] Server started
print(warning_log('Low memory'))       # [WARNING] Low memory

Возврат нескольких функций

def create_math_functions():
    """Возвращает набор математических функций"""
    def add(a, b):
        return a + b
    
    def subtract(a, b):
        return a - b
    
    def multiply(a, b):
        return a * b
    
    return add, subtract, multiply

add, subtract, multiply = create_math_functions()

print(add(5, 3))      # 8
print(subtract(5, 3))  # 2
print(multiply(5, 3))  # 15

Возврат с использованием lambda

def create_power_function(n):
    """Возвращает функцию возведения в степень n с использованием lambda"""
    return lambda x: x ** n

square = create_power_function(2)
cube = create_power_function(3)

print(square(5))  # 25
print(cube(5))    # 125

Композиция функций

def compose(f, g):
    """Возвращает композицию двух функций: (f ∘ g)(x) = f(g(x))"""
    def composed(x):
        return f(g(x))
    return composed

def add_one(x):
    return x + 1

def multiply_by_two(x):
    return x * 2

# Сначала умножаем на 2, потом добавляем 1
operation = compose(add_one, multiply_by_two)
print(operation(5))  # (5 * 2) + 1 = 11

Высокоуровневые функции (higher-order functions)

def apply_function(func, items):
    """Применяет функцию к каждому элементу"""
    return [func(item) for item in items]

def create_doubler():
    """Возвращает функцию удвоения"""
    return lambda x: x * 2

doubler = create_doubler()
result = apply_function(doubler, [1, 2, 3, 4, 5])
print(result)  # [2, 4, 6, 8, 10]

Тип возвращаемого значения

from typing import Callable

# Указываем, что функция возвращает функцию
def create_adder(n: int) -> Callable[[int], int]:
    """Возвращает функцию, которая добавляет n к её аргументу"""
    def add(x: int) -> int:
        return x + n
    return add

add_5: Callable[[int], int] = create_adder(5)
print(add_5(10))  # 15

Ключевые моменты

  • Да, можно возвращать функции — они объекты первого класса
  • Замыкание (closure) — функция может использовать переменные внешней функции
  • Декораторы — частный случай возврата функций
  • Фабрики функций — полезны для создания семейств похожих функций
  • Высокоуровневые функции — функции, работающие с другими функциями
  • Type hints — можно указывать Callable для типизации
  • Функциональное программирование — в Python это естественный способ работы
Можно ли вернуть из функции функцию? | PrepBro