I have looked all over but it is a hard topic to search for without lots of noise. I want to do something like this:
return arg * arg
def add(self, other):
return self * other
f.__add__ = add
cubefunction = f + f
TypeError: unsupported operand type(s) for +: 'function' and 'function'
>>> from functional import compose
>>> def add(a, b):
... return a + b
>>> def double(a):
... return 2 * a
>>> compose(double, add)(5, 6)
I don't think you can do this. However, using the
__call__ magic method lets you define your own callable class which acts as a function and upon which you can define
>>> class FunctionalFunction(object): ... def __init__(self, func): ... self.func = func ... ... def __call__(self, *args, **kwargs): ... return self.func(*args, **kwargs) ... ... def __add__(self, other): ... def summed(*args, **kwargs): ... return self(*args, **kwargs) + other(*args, **kwargs) ... return summed ... ... def __mul__(self, other): ... def composed(*args, **kwargs): ... return self(other(*args, **kwargs)) ... return composed ... >>> triple = FunctionalFunction(lambda x: 3 * x) >>> times_six = triple + triple >>> times_six(2) 12 >>> times_nine = triple * triple >>> times_nine(3) 27
+ is overloaded to pointwise addition, and
* to composition. Of course, you can do anything you like.
Interesting question for the Python gurus: why does the following not work (filthy hack though it is)?
>>> from types import MethodType, FunctionType >>> f = lambda: None >>> f.__add__ = MethodType(lambda self, other: "summed!", f, FunctionType) >>> f.__add__(f) 'summed!' >>> f + f Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'function' and 'function'