Функции как объекты в Python — разбор примера с лямбдами

Функции как объекты в Python — разбор примера с лямбдами

@python_quiz

Разберем этот квиз

Короткий и конкретный пример показывает важную особенность Python: функции — объекты первого класса. Разберём, как именно формируется результат и почему вывод программы — именно тот, который ожидается.

Исходный код

python

Пошаговый разбор

  1. make_ops принимает два аргумента — f и g — и возвращает список из трёх объектов:

- первый элемент — f (сама функция),
- второй — g (сама функция),
- третий — лямбда, которая при вызове применяет g к x, а затем f к результату (f(g(x))).

  1. add1 — функция, прибавляющая 1 к аргументу.
  2. mul2 — функция, умножающая аргумент на 2.
  3. В выражении [op(3) for op in make_ops(add1, mul2)] мы:

- получаем список функций/лямбды от make_ops,
- для каждой функции вызываем её с аргументом 3,
- собираем результаты в список.

Вычисления для каждого элемента:

  • f(3) = add1(3) = 3 + 1 = 4
  • g(3) = mul2(3) = 3 * 2 = 6
  • лямбда: f(g(3)) = add1(mul2(3)) = add1(6) = 7

Итоговый вывод: [4, 6, 7]

Почему другие варианты неверны

  • Вариант с третьим элементом 8 мог бы появиться, если бы лямбда вычисляла g(f(x)) (т.е. присваивала бы порядок вызова наоборот): mul2(add1(3)) = 2 * 4 = 8.
  • Вариант с 5 был бы возможен, если бы третья функция делала что-то вроде f(f(3)) или возвращала фиксированное значение, но в данном коде этого не происходит.
  • Вариант с 9 предполагает сумму или композицию, дающую 9; в текущей композиции f(g(3)) = 7, так что 9 — не результат.

Таким образом, правильный вывод — [4, 6, 7], потому что третья функция явно реализует композицию f(g(x)).

Небольшие замечания о замыканиях и поведении лямбд

  • Лямбда внутри make_ops захватывает переменные f и g из окружения функции. Это обычное поведение замыканий: лямбда будет ссылаться на те объекты f и g, которые были переданы в make_ops.
  • Важно помнить про «позднее связывание» (late binding) при создании лямбд в цикле: если лямбда ссылается на переменную цикла, все лямбды могут разделять последнее значение переменной. В данном примере такой проблемы нет, так как f и g — явные аргументы функции.

Пример проблемы позднего связывания и способа её избежать:

python

Дополнительные примеры и вариации

Покажем, как быстро изменить порядок композиции, чтобы получить другой результат:

python

Здесь третья функция вычисляет mul2(add1(3)) = 8.

Вывод

Этот короткий пример — хорошая иллюстрация:

  • функций как объектов первого класса,
  • композиции функций и порядка вызова,
  • замыканий в Python и возможных подводных камней (позднее связывание).

Понимание этих механизмов помогает предсказывать поведение кода и избегать ошибок при построении более сложных функциональных конструкций.

Report Page