You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python try-except-finally执行顺序规则验证及相关疑问

Python try-except-finally 执行顺序测试与验证

测试背景

之前很少使用finally代码块,为了规范使用先开展了测试,以下是测试过程和疑问。

第一段测试代码及结果

代码:

def f():
    try:
        1/0
        # 1/1
    except:
        print('except')      # 1
        raise                # 2
    finally:
        print('finally')     # 3

try:
    f()
except:
    print("haha")

执行结果:

except
finally
haha

总结的执行顺序规则及疑问

基于这段测试,我总结出执行顺序规则:

  • 执行except块中除raise语句(若存在)外的所有内容;
  • 执行finally块;
  • 回到except块执行raise语句(若存在)。

请问该规则是否正确?另外,except块中除raise外,是否还有其他会延迟到finally块之后执行的语句?

第二段测试示例(更直观)

代码:

def f():
    try:
        1/0
        # 1/1
    except:
        print('except')    #1
        raise print("a")   #2  # 无实际意义,仅用于观察执行顺序         
    finally:
        print('finally')   #3

执行结果:

except
a
finally
foo

解答

你的总结方向是对的,但可以更精准地理解底层逻辑:

  • 当except块中出现raise时,raise的异常抛出动作会延迟到finally执行完成后,但raise语句里的表达式(比如第二段中的print("a"))会在当前位置立即执行,不会延迟。
  • 除了raise,return、break、continue这类改变控制流的语句,它们的生效动作也会被延迟到finally执行后。比如except块里写return 1,会先执行完finally的代码,再真正返回值。

举个return的验证例子:

def f():
    try:
        1/0
    except:
        print('except')
        return 1
    finally:
        print('finally')

print(f())

执行结果:

except
finally
1

这里return 1的返回动作要等finally执行完毕才会完成。

本质上,finally的设计核心就是:无论try/except块中发生什么(正常结束、抛出异常、return/break等),都会在离开try语句块前执行。所以当except块中有改变控制流的语句时,这些语句的“最终生效步骤”会被挂起,先执行finally,再完成控制流的变更。


内容的提问来源于stack exchange,提问作者Basj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 20:33:10