python函数参数评估模型

发布于 2024-08-30 04:25:06 字数 823 浏览 4 评论 0原文

我正在看 Peter Norvig 网站上的一篇文章,他试图回答以下问题(顺便说一句,这不是我的问题) “我可以在 Python 中执行相当于(测试?结果:替代)的操作吗?”

这是他列出的选项之一,

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 评估模型的指导,这可能有助于我的理解。

谢谢!

I was looking at an article on Peter Norvig's website, where he's trying to answer the following question (this is not my question, btw)
"Can I do the equivalent of (test ? result : alternative) in Python?"

here's one of the options listed by him,

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

And here's a usage example.

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

I understand how this works (I think), but I was just playing with the code, and decided to see what happens when I change the third argument in the definition of 'fact' above to
n * fact(n-1), that is, change it to a non-callable expression. On running it, the interpreter goes into a never ending loop. I have a pretty good idea of why that is happening, that is, the if_ function is returning back the same expression that it is receiving. But what is the type of that expression? What exactly is going on here? I am not looking for a detailed explanation , but just for some pointers to python's evaluation model which might help my understanding.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜血缘 2024-09-06 04:25:06

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

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

(我相信)这被称为急切求值,其中函数参数在传递给函数之前先求值。在惰性求值方案中,参数只有在函数体中使用时才会被求值。

The reason the loop never terminates when you change fact to n * fact(n-1) is that n * fact(n-1) has to evaluate first (as the third argument to if). Evaluating it leads to another call to fact, ad infinitum (since there is no longer any base case to stop it).

Previously, you were passing a function object (lambda), which would not be evaluated until the body of if, and its result would be checked via test.

This is known (I believe) as eager evaluation, where function arguments are evaluated before they are passed to the function. In a lazy-evaluation scheme, the arguments would not be evaluated until they were used in the function body.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文