如何添加功能

发布于 2024-09-30 20:40:56 字数 899 浏览 6 评论 0原文

我已经查遍了,但这是一个很难在没有太多噪音的情况下搜索的主题。我想做这样的事情:

def f(arg):
  return arg * arg

def add(self, other):
  return self * other

f.__add__ = add

cubefunction = f + f

但是我在对cubefunction赋值时遇到错误,例如:

TypeError: unsupported operand type(s) for +: 'function' and 'function'

Python中没有可能的函数代数还是我只是犯了一个愚蠢的错误?

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

东京女 2024-10-07 20:40:56

我不认为你能做到这一点。但是,使用 __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

这里 < code>+ 重载为逐点加法,* 重载为复合。当然,您可以做任何您喜欢的事情。


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

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'
萌逼全场 2024-10-07 20:40:56

我认为你的意思是:

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

I think what you mean to do is:

cubefunction = (lambda x: add(f(x), f(x)))
陌伤ぢ 2024-10-07 20:40:56

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

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.

网白 2024-10-07 20:40:56

嗯,我想我得到了一些有趣的东西来添加功能。这是关于 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

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
倾城泪 2024-10-07 20:40:56

有点晚了,但是使用 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 函数)

您可以用它做各种有趣的事情。假设您要为给定的 n 定义函数 f(x) = 1 + x + x**2 + ... + x**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-define-in-a-loop-with- different-values-all-return-the-same-result

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文