user318904 user318904 - 2 years ago 100
Python Question

How to add functions

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 (, and towards the bottom it references a third party package "functional" (, 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)

Answer Source

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)
>>> times_nine = triple * triple
>>> times_nine(3)

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)
>>> f + f
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'function' and 'function'
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download