2

我正在查看 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

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

谢谢!

4

1 回答 1

4

当您更改为时,循环永远不会终止的原因factn * fact(n-1)必须n * fact(n-1)首先评估(作为 的第三个参数if)。评估它会导致另一个调用fact, ad infinitum (因为不再有任何基本情况来阻止它)。

以前,您传递的是一个函数对象 ( lambda),它在 的主体之前不会被评估if,其结果将通过test.

这被称为(我相信)急切评估,其中函数参数在传递给函数之前被评估。在惰性求值方案中,在函数体中使用参数之前,它们不会被求值。

于 2010-04-26T19:44:16.770 回答