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:
def f(arg):
return arg * arg
def add(self, other):
return self * other
f.__add__ = add
cubefunction = f + f
But I get errors on the assignment to cubefunction like:
TypeError: unsupported operand type(s) for +: 'function' and 'function'
Is there no function algebra possible in python or am I just making a dumb mistake?
edit: much later, I was reading Python's official intro to functional programming (http://docs.python.org/howto/functional.html), and towards the bottom it references a third party package "functional" (http://oakwinter.com/code/functional/documentation/), which can compose functions, ie:
>>> from functional import compose
>>> def add(a, b):
... return a + b
...
>>> def double(a):
... return 2 * a
...
>>> compose(double, add)(5, 6)
22
Just like we can add and subtract numbers, we can add and subtract functions. For example, if we had functions f and g, we could create two new functions: f + g f+g f+g and f − g f-g f−g .
To add or subtract functions, just add or subtract the values at each point where it makes sense. If the functions are given by formulas, you can just add or subtract the formulas (it doesn't matter whether you plug in values before or after).
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 __add__
:
>>> 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
Here +
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'
I think what you mean to do is:
cubefunction = (lambda x: add(f(x), f(x)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With