【发布时间】:2020-01-08 05:10:49
【问题描述】:
我正在阅读 python 文档以改进我的核心 python,我正在阅读关于 errors and exceptions
在文档中它说
如果 finally 子句包含 return 语句,则 finally 子句的 return 语句将在 try 子句中的 return 语句之前执行,而不是。
下面还提供了这个例子:
def bool_return():
try:
return True
finally:
return False
bool_return()
现在看这个例子,上面的陈述似乎很直截了当,但如果你稍微修改一下这个例子,让它看起来像这样:
def bool_return():
try:
return print("foo")
finally:
return False
bool_return()
现在,如果你运行它,你会看到foo 将被打印出来,并且 False 将被返回。现在文档说 finally 子句的 return 将执行 before,而 而不是, try 子句的 return 语句。如果是这样,那为什么我可以看到正在打印的 foo?
我用pycharm调试了这个sn-p,它显示首先执行try子句的return语句并打印字符串,然后由于return语句而返回None的输出,以及return语句在 finally 子句中将稍后执行,这是程序的最后一次返回,因此该函数会覆盖先前的返回并返回 False。
我的问题是:
1) 为什么doc说finally子句的return语句在之前执行?
2) 为什么doc说finally子句的return语句被执行而不是 try子句的return语句?
我认为这两种说法都与现实情况相反。
编辑:
阅读@iBug 的答案后,现在很清楚print("foo") 是如何评估的,但None 没有返回。基本上,首先计算表达式,然后发生return。后来return False in finally 被执行。这清楚地说明了为什么我们会得到我们所做的输出。
不过,我看到 finally 中的 return False 是在 try 的 return print("foo") 之后执行的。
或者根据@iBug 的评论,10 RETURN_VALUE 完全被绕过了?
编辑
这已在文档中得到解决,现在返回的内容是正确的。但是,如果您想知道“如何”,请阅读所有 cmets 并仔细回答。
【问题讨论】:
-
有时文档写得不太好。
-
return print("foo")实际上是2个单独的步骤,首先调用打印函数,然后将返回值None分配给return语句 - 然后 finally块返回语句覆盖先前的语句值。这有点过于简化了,但你明白我的意思 -
@IainShelvington:你可以把它分解成更多的步骤(加载
print,加载"foo",调用函数,返回值,对于初学者),但所有这些步骤都是执行的一部分return声明。返回值计算与实际返回值是分开的,但它与整个return语句并不分开。 -
措辞不好——怎么可能既是before又是instead of,这些是相互排斥的概念。
-
这是文档PR here 中的最新更改,令人困惑的措辞似乎直接取自this github comment。有other problems从同一个PR中引入。
标签: python python-3.x try-except finally