开发者

How to add functions

开发者 https://www.devze.com 2023-01-23 08:12 出处:网络
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:

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


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)))


In your code, f needs to be a class, not a function. If you have a class, you can implement an add(self, other) method that will overload the + operator.


Well I think I got something interesting to add functions. It's about lambda function and it could fix your problem. At least it fixed mine :

>>> def func( x ) :
>>>     return x
>>> 
>>> f = lambda x : func( x )
>>> sum_of_f = [ f for i in range( 5 ) ]
>>> F = lambda x : sum( [ i( x ) for i in sum_of_f ] ) 
>>> F( 1 )
5
>>> F( 2 )
10

and for those who are interested to pass parameters

>>> def func( x, p ) :
>>>     return x * p
>>>
>>> param = [ 0, 1, 2, 3, 4 ]
>>> 
>>> f = lambda x, p : func( x, p )
>>> sum_of_f = [ f for i in range( 5 ) ]
>>> F_bis = lambda x : sum( [ sum_of_f[i]( x, param[i] ) for i in range( 5 ) ] )
>>> F_bis( 1 )
10
>>> F_bis( 2 )
20


A bit late, but this kind of algebra can be done easily using lambda functions:

>>> f = lambda x: x*x
>>> g = lambda x: x*x
>>> h = lambda x: f(g(x))
>>> h(2)
16
>>> j = lambda x: f(x) + g(x)
>>> j(2)
8
>>>

(f and g do not need to be lambda functions)

You can do all sorts of interesting things with this. Let's say you want to define the function f(x) = 1 + x + x**2 + ... + x**n for a given n. You can do:

>>> n = 3
>>> f = lambda x: 1
>>> for i in range(n):
...     f = lambda x, j = i + 1, k = f: k(x) + x**j
... 
>>> f(2)
15

to understand why I made the lambda that way (lambda x, j = i + 1, k = f:) is better to read this: https://docs.python.org/3.5/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result

Long story short: the parameters in a lambda function do not have a local copy. If I had used the ifrom the loop as in lambda x, k = f: k(x) + x**(i + 1), we would have had the function f(x) = 1 + x**3 + x**3 + x**3.

0

精彩评论

暂无评论...
验证码 换一张
取 消