Funktoren oder Funktorobjekte sind einfacher lesbare lambda-Ausdrücke. C++ Programmierer kennen sie vielleicht von Boost.
1 def _genmethod(func, op):
2 return lambda self, *a, **k: func(self, op, *a, **k)
3
4 class Functor:
5 def __init__(self, paramgetter):
6 self.paramgetter = paramgetter
7 def __call__(self, *args, **kwargs):
8 return self.paramgetter(*args, **kwargs)
9 def _bifunc(self, op, other):
10 if isinstance(other, Functor):
11 return Functor(lambda *a, **k: op(self.paramgetter(*a, **k), other(*a, **k)))
12 return Functor(lambda *a, **k: op(self.paramgetter(*a, **k), other))
13 __add__ = _genmethod(_bifunc, lambda a,b: a+b)
14 __sub__ = _genmethod(_bifunc, lambda a,b: a-b)
15 __mul__ = _genmethod(_bifunc, lambda a,b: a*b)
16 __div__ = _genmethod(_bifunc, lambda a,b: a/b)
17 __radd__ = _genmethod(_bifunc, lambda a,b: b+a)
18 __rsub__ = _genmethod(_bifunc, lambda a,b: b-a)
19 __rmul__ = _genmethod(_bifunc, lambda a,b: b*a)
20 __rdiv__ = _genmethod(_bifunc, lambda a,b: b/a)
21
22 _0 = Functor(lambda *a, **k: a[0])
23 _1 = Functor(lambda *a, **k: a[1])
24 _2 = Functor(lambda *a, **k: a[2])
Ein einfaches Beispiel:
1 e = 3 * _0 + _1
2 print e(1, 3), e(2, 2), e(3, 1)
Es sollte folgendes ausgeben:
6 8 10