<p>你的代码</p>
<pre class="lang-py prettyprint-override"><code>def bool_return():
try:
return print("foo")
except:
pass
finally:
return print("ola")
print(bool_return())
</code></pre>
<p>正在使用<code>finally</code>子句。finally子句在退出拥有的<code>try</code>/<code>except</code>块之前执行。这意味着您可能会被提交到以下(伪代码!):</p>
<pre><code>function bool_return():
do in case of errors goto Errors:
var r = print("foo") < this is the statement in the try block
print("ola") < this is the statement in the finally one
return r
Errors:
do nothing < this is the pass instruction.
var r = print ("ola")
return r
print(bool_return())
</code></pre>
<p>暂时忽略可能不正确的<code>return</code>语句,问题的罪魁祸首是解释器如何运行语句:</p>
<pre><code> return print("foo")
</code></pre>
<p>它被分成两部分</p>
<pre><code>var r = print("foo") < this is the statement in the try block
return r
</code></pre>
<p>然后在返回之前执行finally的内容</p>
<pre><code>var r = print("foo") < this is the statement in the try block
print ("ola")
return r
</code></pre>
<p>这是因为<code>try</code>块的语义如下</p>
<ul>
<li>运行<code>try</code>块中包含的任何内容。如果运行时没有错误,则存储返回值(如果存在),然后运行<code>finally</code>块的内容。如果这里没有出现错误,并且我们有一个返回值,只需返回存储的返回值即可</li>
<li>如果<code>try</code>块有错误,则运行<code>except</code>块中的内容(如果存在)。如果此处没有错误,则存储返回值(如果存在),运行<code>finalize</code>块,如果此处没有错误,则仅返回存储的返回值</li>
<li>如果<code>except</code>块出错,则停止执行并运行<code>finally</code>块。然后将异常传播到外部块</李>
<li>现在事情可能变得一团糟,因为您可以(并且将)嵌套多个<code>try</code>块。上述步骤递归重复,直到异常得到处理或到达解释器<code>try</code>块。在后一种情况下,应用程序被停止,异常以通常的<code>traceback</code>语法打印到控制台</李>
</ul>
<p>这只是为了让您了解它是如何工作的。某些细节可能会遗漏或可能不是100%正确。如果您想了解更多信息,可以在<a href="https://www.w3schools.com/python/python_try_except.asp" rel="nofollow noreferrer">W3C</a>玩异常游戏并了解更多<a href="https://docs.python.org/3/tutorial/errors.html" rel="nofollow noreferrer">here</a></p>