Знаком ли ты с понятием функций первого класса в Python
Что проверяют
Понимаете ли вы, что функция в Python это обычный объект, и умеете ли этим пользоваться. Вопрос почти всегда ведёт дальше: к замыканиям и декораторам, а иногда к классической ловушке с lambda в цикле.
Как отвечать
Функция первого класса означает, что с ней можно делать всё то же, что с любым значением:
- присвоить переменной:
handler = processбез скобок, это ссылка на объект, а не вызов; - передать аргументом:
sorted(users, key=lambda u: u.age),map,filter, колбэки,functools.partialдля фиксации части аргументов; - вернуть из функции: фабрика
make_multiplier(2)возвращает новую функцию, которая помнитfactor; - хранить в структурах: словарь диспетчеризации
{"csv": parse_csv, "json": parse_json}вместо цепочкиif/elif; - иметь атрибуты: у функции есть
__name__,__doc__,__defaults__,__closure__, можно добавить и свой атрибут.
Отдельно разведите термины. Функции первого класса это свойство языка, а функция высшего порядка это функция, которая принимает или возвращает другую функцию. Замыкание это внутренняя функция, которая держит ссылки на переменные внешней области видимости. Чтобы переприсвоить такую переменную изнутри, нужен nonlocal.
На этом стоят декораторы: запись @timer над def f равносильна f = timer(f). Внутри обёртки стоит использовать functools.wraps, иначе у задекорированной функции пропадут имя и docstring.
Где спотыкаются
Попадают на позднее связывание: [lambda: i for i in range(3)] даст три функции, и все вернут 2, потому что i читается в момент вызова. Лечится аргументом по умолчанию: lambda i=i: i.
Передают результат вместо функции: callback=handler() вызывает функцию сразу и передаёт то, что она вернула.
Путают функции первого класса с функциями высшего порядка или отвечают одним определением, без примера из своего кода, где это пригодилось.