Что такое функция высшего порядка в Python
Что проверяют
Владеете ли вы функциями как значениями на рабочем уровне: замыкания, декораторы, аннотации типов. Для питониста это не терминологический вопрос, а вход в разговор про декораторы, которые есть в любом проекте.
Как отвечать
Функция высшего порядка принимает функцию аргументом или возвращает функцию. В Python функции это объекты первого класса, поэтому их присваивают переменным, кладут в словари и передают дальше.
Канонический пример это декоратор, то есть функция, которая принимает функцию и возвращает обёртку:
import functools, time
def timed(func):
@functools.wraps(func) # сохраняет имя и строку документации
def wrapper(*args, **kwargs):
start = time.perf_counter()
try:
return func(*args, **kwargs)
finally:
print(func.__name__, time.perf_counter() - start)
return wrapperСтоит назвать и повседневные случаи: sorted с key=operator.itemgetter(1), functools.partial для фиксации аргумента, кеширование через functools.lru_cache, диспетчеризация словарём функций вместо длинной цепочки условий. Про типизацию: параметр объявляется как Callable, а декоратору, сохраняющему сигнатуру обёрнутой функции, нужен ParamSpec.
Где спотыкаются
Пишут декоратор без functools.wraps. Обёртка подменяет имя, документацию и сигнатуру, ломая интроспекцию и инструменты, которые ищут функцию по имени.
Захватывают переменную цикла в замыкании. Функции, созданные в цикле, все вернут последнее значение переменной: замыкание держит саму переменную, а не её значение на момент создания. Лечится аргументом по умолчанию или functools.partial.
Возвращают вызов вместо функции. В фабрике пишут return multiply(x) там, где нужно return multiply, и наружу уходит уже посчитанное число, а вызвать результат как функцию не получается.