08 января 2010

Карринг и композиция в Python

При программировании на Python в функциональном стиле часто возникает необходимость в использовании такой классической операции, как карринг. Как оказалось, в стандартной библиотеке языка присутствует модуль functools, в котором реализована эта возможность. В двух словах, карринг — это конструирование новой функции на основе существующей путем частичного определения значений аргументов. Например:

from functools import partial
def plus(x, y): return x + y
plus2 = functools.partial(plus, 2) # определяем новую функцию как функцию plus,
# одним из аргументов которой будет число 2
plus2(2) # результатом будет 4
Для приведенного выше примера можно использовать стандартный модуль operator, который содержит функции, аналогичные математическим операторам языка:
from operator import  add # импортируем функцию сложения двух значений
map(functools.partial (add, 2), range(10)) # результат — [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Еще больше функциональных возможностей предоставляет модуль functional, к сожалению, не входящий в стандартные средства языка. Кроме всего прочего, этот модуль позволяет определять функцию, как композицию нескольких существующих функций. К примеру, определение g = f(h(x)):
import functional
g = functional.compose(f, h)
Если определить функцию, которая проверяет число на нечетность:
def odd(x): return x % 2
, то на ее основе легко можно построить функцию, проверяющую на четность (функция partial есть и в functional):
even = functional.compose (odd, functional.partial (add, 1))
Тогда
filter(even, range(10))
вернет [0, 2, 4, 6, 8].
Эти возможности особенно полезны для call-back-функций, например при описании реакций на события.

Комментариев нет: