【问题标题】:Functions as arguments to functions函数作为函数的参数
【发布时间】:2013-04-10 22:59:34
【问题描述】:

我在一本 Python 书籍中看到了这个例子,它展示了如何使用一个函数作为另一个函数的参数:

def diff2(f, x, h=1E-6):
    r = (f(x-h) - 2*f(x) + f(x+h))/float(h*h)
    return r

def g(t):
    return t**(-6)

t = 1.2
d2g = diff2(g, t)
print d2g

我的问题是,如果不向函数 g 提供参数,这个脚本是如何工作的?有问题的行是:

d2g = diff2(g,t)

不应该是这样吗:

d2g = diff2(g(t), t)

【问题讨论】:

  • g(t) 在你的最后一行会告诉g 使用参数t 执行,这不是你想要的。

标签: python function arguments


【解决方案1】:

g 作为参数传递给diff2。在diff2 中,该参数称为f,因此在diff2 中,名称f 指的是函数g。当diff2 调用f(x-h)(和其他调用)时,它调用g,并提供参数。

换句话说,当您执行diff2(g, t) 时,您是在告诉diff2 g 是要调用的函数。 g 的参数在 diff2 中提供:

f(x-h) # calls g with x-h as the argument
f(x)   # calls g with x as the argument
f(x+h) # calls g with x+h as the argument

如果您调用diff2(g(t), t),您将传递g(1.2)结果 作为参数。 g 会在调用diff2 之前被调用,而diff2 在尝试调用f 时会失败,因为f 将是一个数字(值g(1.2))而不是一个函数。

【讨论】:

  • 我稍微修改了我的问题。让我感到困惑的是,在上面的示例中,我们从未为函数 g 提供参数。
  • @marillion:正如我所写的,你做到了。您只是不要在diff2(g, t) 行中调用g。你所做的就是告诉diff2 调用什么函数,然后diff2 调用它,提供当时的参数。
  • 我可能错了,但是python中的函数是一流的对象。
  • @BrenBarn 谢谢你的解释,花了我一段时间,但我终于明白了。
【解决方案2】:

所讨论的函数相当随机,而且可能难以理解。让我们考虑一个简单的例子,一个函数sum,它接受两个数字ab,并返回它们的总和。实际上,我们可以很容易地定义另一个函数prod,它也返回他们的产品。

def sum(a,b):
    return a + b

def prod(a,b):
    return a * b

假设我们有另一个函数compute,它将操作(一个函数)和两个操作数(调用函数的两个数字)作为其参数。在compute 中,我们对参数调用给定的操作。

def compute(fn, a, b):
    return fn(a, b)

我们可以compute 不同的东西。我们可以compute两个数字的sum

compute(sum, 1, 3)

我们可以compute两个数字的乘积:

compute(prod, 1, 3)

基本上,函数名后面没有括号,我们实际上并没有调用函数,它只是命名空间中的另一个对象(恰好是我们可以调用的函数)。直到在compute 内部,当我们调用fn(a,b) 时,我们才会调用该函数。

让我们看看控制台输出是什么样子的:

>>> compute(sum,1,3)
4
>>> compute(prod,1,3)
3
>>> sum
<function sum at mem-address>
>>> prod
<function prod at mem-address>
>>> sum(1,2)
3

【讨论】:

  • 非常感谢您的清晰解释。这:“我们实际上并没有调用该函数,它只是命名空间中的另一个对象”以及 BrenBran 的回复对我理解发生了什么帮助很大。