Python函数参数评估模型

2 投票
1 回答
2118 浏览
提问于 2025-04-15 22:02

我在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 个回答

4

当你把 fact 改成 n * fact(n-1) 时,循环永远不会结束的原因是 n * fact(n-1) 必须先计算(作为 if 的第三个参数)。这个计算会导致再次调用 fact,这样就会一直重复下去(因为没有基础情况来停止它)。

之前,你传递的是一个函数对象(lambda),这个对象不会在 if 的主体执行之前被计算,它的结果会通过 test 来检查。

这被称为“急切计算”,也就是函数的参数在传递给函数之前就被计算了。而在“懒惰计算”的情况下,参数只有在函数体内被使用时才会被计算。

撰写回答