如何添加功能

时间:2010-11-04 20:49:56

标签: python functional-programming operators

我看了一遍,但搜索没有大量噪音是一个难题。我想做这样的事情:

def f(arg):
  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'

在python中是否可以使用函数代数,或者我只是犯了一个愚蠢的错误?

编辑:很久以后,我正在阅读Python官方编程的正式介绍(http://docs.python.org/howto/functional.html),并在底部引用第三方包“functional”(http://oakwinter.com/code/functional/documentation/),它可以组成函数,即:

>>> from functional import compose
>>> def add(a, b):
...     return a + b
...
>>> def double(a):
...     return 2 * a
...
>>> compose(double, add)(5, 6)
22

6 个答案:

答案 0 :(得分:6)

我认为你不能这样做。但是,使用__call__魔术方法可以定义自己的可调用类,该类充当函数,可以定义__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

此处+重载为逐点添加,*重叠为合成。当然,你可以做任何你喜欢的事情。


Python专家的有趣问题:为什么以下不起作用(虽然它是肮脏的黑客)?

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

答案 1 :(得分:1)

我认为你的意思是:

cubefunction = (lambda x: add(f(x), f(x)))

答案 2 :(得分:1)

在你的代码中,f需要是一个类,而不是一个函数。如果你有一个类,你可以实现一个 add (self,other)方法,它会使+运算符重载。

答案 3 :(得分:1)

我认为我有一些有趣的东西来添加功能。这是关于lambda函数,它可以解决你的问题。至少它固定了我的:

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

以及有兴趣传递参数的人

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

答案 4 :(得分:1)

有点晚了,但是这种代数可以使用lambda函数轻松完成:

>>> 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和g不需要是lambda函数)

你可以用这个来做各种有趣的事情。假设您要为给定的f(x) = 1 + x + x**2 + ... + x**n定义函数n。你可以这样做:

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

理解为什么我以这种方式制作lambda(lambda x, j = i + 1, k = f:)更好地阅读:https://docs.python.org/3.5/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result

长话短说:lambda函数中的参数没有本地副本。如果我在i中使用了循环中的lambda x, k = f: k(x) + x**(i + 1),那么我们就会拥有f(x) = 1 + x**3 + x**3 + x**3函数。

答案 5 :(得分:-2)