【问题标题】:product of two functions两个函数的乘积
【发布时间】:2012-02-18 10:01:33
【问题描述】:

我有两个函数,fg。两者具有相同的签名:(x)。我想创建一个具有相同签名的新函数z

def z(x):
  return f(x) * g(x)

除了我想能够写

z = f * g 而不是上面的代码。有可能吗?

【问题讨论】:

  • 不要这么认为 - 没有为函数参数定义运算符。

标签: python functional-programming python-3.x


【解决方案1】:

接近的东西可能的:

z = lambda x: f(x) * g(x)

就我个人而言,我觉得这种方式比z = f * g 更直观,因为在数学上,乘法函数没有任何意义。根据* 运算符的解释,它可能意味着composition 所以z(x) = f(g(x)),但绝对不是调用结果的乘法。另一方面,上面的lambda 非常明确,坦率地说,只需要多写一点字符。


更新: 感谢 JBernardo 将它一起破解。我在想象它会比原来更hacky。不过,我建议不要在实际代码中使用它。

【讨论】:

  • 啊,是的,当然。我同意 f * g 看起来模棱两可,所以无论如何我宁愿使用 lambda。
  • 不确定 lambda 在这种情况下是否有用。并不是说我的答案没有使用它,而只是为了证明它是可能的。在您的情况下,您只会失去函数名称(z)而没有任何好处。我认为def 声明仍然更好。
  • @JBernardo:为什么“松散函数名”?该函数归属于名称 z,就好像它是 def'ef。除非您指的是内部 __name__ 属性 - 无论如何也不会造成太大损失。
【解决方案2】:

有趣的是,这很有可能。几天前我做了一个项目来做这样的事情。

这里是:FuncBuilder

到目前为止,您只能定义变量,但您可以使用我的元类并借助其他一些函数来构建您想要的类。

问题:

  • 很慢
  • 真的很慢
  • 您认为您需要这样做,但按照应有的方式描述函数是正确的方式。

您应该使用您的第一个代码。

作为概念证明:

from funcbuilder import OperatorMachinery

class FuncOperations(metaclass=OperatorMachinery):
     def __init__(self, function):
          self.func = function
     def __call__(self, *args, **kwargs):
          return self.func(*args, **kwargs)

def func(self, *n, oper=None):
    if not n:
        return type(self)(lambda x: oper(self.func(x)))
    return type(self)(lambda x: oper(self.func(x), n[0](x)))

FuncOperations.apply_operators([func, func])

现在你可以这样编码了:

@FuncOperations
def f(x):
    return x + 1

@FuncOperations
def g(x):
    return x + 2

而期望的行为是:

>>> z = f * g
>>> z(3)
20

我在FuncBuilder 项目中添加了一个更好的版本。它适用于FuncOperation 对象和另一个可调用对象之间的任何操作。也适用于一元运算。 :D

您可以使用它来制作如下功能:

z = -f + g * h

【讨论】:

  • 我开始编写一个类来向自己证明它可以很容易地完成,但这要优雅得多,非常好:)
  • 我在我的项目中使用了你的想法,到目前为止效果很好。我没有使用元类。元类与简单地在FuncOperations 中定义您需要的所有运算符相比有什么优势? (我发布了一些示例代码here。)
  • @max 我喜欢元类,因为以后扩展代码的工作并不多(就像我在上面为函数创建新行为所做的那样)。但是请随意使用您已经习惯的东西,因为一开始创建元类可能有点困难。
【解决方案3】:

通过使用装饰器,我可以使用您想要的确切语法(尽管使用 lambda 可能会更好)。如前所述,函数没有为它们定义运算符,但对象可以像 Python 中的函数一样被调用—— 所以下面的装饰器只是将函数包装在一个对象中,该对象定义了另一个函数的乘法:

class multipliable(object):
    def __init__(self, func):
        self.func = func
    def __call__(self, *args, **kw):
        return self.func(*args, **kw)
    def __mul__(self, other):
        @multipliable
        def new_func(*args, **kw):
            return self.func(*args, **kw) * other(*args, **kw)
        return new_func

@multipliable
def x():
    return 2

(在 Python 2 和 Python 3 中测试)

def y():
    return 3

z = x * y
z()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-25
    • 1970-01-01
    • 2015-09-30
    • 2020-06-03
    • 2013-03-31
    • 1970-01-01
    相关资源
    最近更新 更多