python函数参数评估模型
我正在看 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您将
fact
更改为n *fact(n-1)
时循环永远不会终止的原因是n *fact(n-1)
必须首先评估(作为if
的第三个参数)。评估它会导致再次调用fact
,无限循环(因为不再有任何基本情况来阻止它)。以前,您传递的是一个函数对象 (
lambda
),该对象在if
主体之前不会被求值,并且其结果将通过test.
(我相信)这被称为急切求值,其中函数参数在传递给函数之前先求值。在惰性求值方案中,参数只有在函数体中使用时才会被求值。
The reason the loop never terminates when you change
fact
ton * fact(n-1)
is thatn * fact(n-1)
has to evaluate first (as the third argument toif
). Evaluating it leads to another call tofact
, 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 ofif
, and its result would be checked viatest
.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.