python函数参数评估模型

时间:2010-04-26 19:25:44

标签: python lambda evaluation callable

我正在查看Peter Norvig网站上的一篇文章,他试图回答以下问题(这不是我的问题,顺便说一句)  “我可以在Python中做相同的(test?result:alternative)吗?”

这是他列出的选项之一,

def if_(test, result, alternative=None):
    "If test is true, 'do' result, else alternative. 'Do' means call if callable."
    if test:
        if callable(result): result = result()
        return result
    else:
        if callable(alternative): alternative = alternative()
        return alternative

这是一个用法示例。

>>> fact = lambda n: if_(n <= 1, 1, lambda: n * fact(n-1))
>>> fact(6)
720

我理解这是如何工作的(我想),但我只是在玩代码,并决定看看当我在上面的'fact'定义中改变第三个参数时会发生什么 n * fact(n-1),即将其更改为不可调用的表达式。在运行它时,解释器进入一个永无止境的循环。我非常清楚为什么会发生这种情况,也就是说,if_函数返回的是它接收的相同表达式。但那个表达的类型是什么?到底发生了什么?我不是在寻找详细的解释,只是为了一些指向python评估模型的指针,这可能有助于我理解。

谢谢!

1 个答案:

答案 0 :(得分:4)

当您将fact更改为n * fact(n-1)时,循环永不终止的原因是n * fact(n-1)必须先评估(作为if的第三个参数)。评估它会导致另一个fact的无限通话(因为不再有任何基本情况可以阻止它)。

以前,您传递了一个函数对象(lambda),在if的正文之前不会对其进行求值,并且会通过test检查其结果。

这是众所周知的(我相信)作为热切评估,其中函数参数在传递给函数之前进行评估。在惰性求值方案中,在函数体中使用参数之前,不会对参数进行求值。