如何创建一个函数,将一个函数应用于 Python 中另一个函数的输入?

How to create a function that applies a function to the inputs of another function in Python?

我正在寻找一种实用的方法来执行以下操作:

def add(x, y):
    return x + y

def neg(x):
    return -x

def c(x, y):
    # Apply neg to inputs for add
    _x = neg(x)
    _y = neg(y)

    return add(_x, _y)

neg_sum = c(2, 2)   # -4

这似乎与柯里化有关,但我能找到的所有示例都使用只有一个输入变量的函数。我想要这样的东西:

def add(x, y):
    return x + y

def neg(x):
    return -x

c = apply(neg, add)
neg_sum = c(2, 2)   # -4

这是一种相当直接的方法:

def add(x, y):
    return x + y

def neg(x):
    return -x

def apply(g, f):
    # h is a function that returns
    # f(g(arg1), g(arg2), ...)
    def h(*args):
        return f(*map(g, args))
    return h

# or this:
# def apply(g, f):
#    return lambda *args: f(*map(g, args))

c = apply(neg, add)
neg_sum = c(2, 2)   # -4

请注意,当您在函数定义中使用 *myvar 作为参数时,myvar 将成为接收到的所有非关键字参数的列表。如果您使用 *expression 作为参数调用一个函数,那么 expression 中的所有项目都会被解包并作为单独的参数发送给该函数。我使用这两种行为让 h 接受一个未知的参数列表,然后将函数 g 应用于每个参数(使用 map),然后将它们作为参数传递给 f.

根据您需要的可扩展性,另一种方法是创建一个对象来实现您的运算符方法,每个 return 相同的对象,允许您以任意顺序将运算符链接在一起.

如果你总是能应付 return 列出一个列表,你也许能够让它发挥作用。

class mathifier:

    def __init__(self,values):
        self.values = values

    def neg(self):
        self.values = [-value for value in self.values]
        return self

    def add(self):
        self.values = [sum(self.values)]
        return self
         
print (mathifier([2,3]).neg().add().values)

而且您仍然可以为任何一组链接函数获取您的命名函数:

neg_add = lambda x : mathifier(x).neg().add()

print(neg_add([2,3]).values)

根据 Matthias Fripp 的回答,我问自己:我想用两种方式编写 addnegadd_neg(*args)neg_add(*args)。这需要稍微破解 Matthias 的建议。这个想法是为了获得一些关于要组成的函数的数量(args 的数量)的提示。由于 inspect 模块,这些信息是通过一些内省获得的。考虑到这一点,我们调整了参数通过函数链传递的方式。这里的主要假设是我们处理数学意义上的实函数,即函数返回一个浮点数,并至少接受一个参数。

from functools import reduce
from inspect import getfullargspec


def arity_one(func):
    spec = getfullargspec(func)
    return len(spec[0])==1 and spec[1] is None

def add(*args):
    return reduce(lambda x,y:x+y, args, 0)

def neg(x):
    return -x

def compose(fun1,fun2):
    def comp(*args):
        if arity_one(fun2): return fun1(*(map( fun2, args)))
        else: return fun1(fun2(*args))
    return comp


neg_add = compose(neg, add)
add_neg = compose(add, neg)

print(f"-2+(-3) = {add_neg(2, 3)}")
print(f"-(2+3) = {neg_add(2, 3)}")

解决方案还是很临时的...