Python 异常处理中 finally 块的执行机制与优先级详解

叶初
叶初
发布时间:2026-10-15 | 5人浏览过
原创

本文深入解析 Python 中 finally 代码块的执行机制。无论是否发生异常或是否包含 return 语句,finally 块均会执行。重点探讨当 try、except 和 finally 中同时存在 return 时,finally 的返回值具有最高优先级,会覆盖其他块的返回结果。此外,还介绍了 try 与 finally 直接配合的使用场景及 Python 2.5 版本前后的语法演变,帮助开发者更规范地处理资源释放与异常清理。

本节将介绍异常处理语法中的另一个重要组成部分——finally 块。掌握 finally 的使用,能够显著提升代码处理异常时的健壮性与逻辑完整性。

finally 的功能与用法

从字面含义理解,finally 表示“最后”。在异常处理语法结构中,它指代最后执行的代码块。

核心特性之一:无论程序运行过程中是否发生异常,finally 代码块内的逻辑必定会被执行。

在函数定义中,即使 try 或 except 分支中已经执行了 return 语句,程序在返回前仍会强制执行 finally 代码块。

语法规范要求:try 语句必须至少搭配 except 或 finally 中的一个使用,不能单独存在。

以下是 finally 的具体用法示例。

try:
    <代码块1>
except:
    <代码块2>
finally:
    <代码块3>

finally 基础示例案例

def test():
    try:
        1 / 0
    except Exception as e:
        print(e)
    finally:
        print('通用异常捕获已完成')


result = test()
print(result)

# >>> 执行结果如下:
# >>> division by zero
# >>> 通用异常捕获已完成

finally 触发的必然性与执行优先级分析

接下来,我们分析在 try 或 except 分支中包含 return 语句时的具体执行流程。

def test():
    try:
        1 / 0
    except Exception as e:
        return e
    finally:
        print('通用异常捕获已完成')


result = test()
print(result)

# >>> 执行结果如下:
# >>> 通用异常捕获已完成
# >>> division by zero

观察上述输出结果可以发现,finally 中的打印语句先于 except 分支的输出执行。

Python 程序通常遵循自上而下的执行顺序,为何会出现这种看似“逆序”的现象?我们在 except 分支中增加一行打印测试代码,以明确实际的执行时序。

def test():
    try:
        1 / 0
    except Exception as e:
        print('exception——test')
        return e
    finally:
        print('通用异常捕获已完成')


result = test()
print(result)

# >>> 执行结果如下:
# >>> exception——test
# >>> 通用异常捕获已完成
# >>> division by zero

结合执行结果可以得出结论,程序逻辑依然是自上而下运行的。造成上述显示顺序差异的根本原因在于:当捕获到异常时,异常信息被赋值给变量 e 并作为返回值。在调用 test() 函数时,该返回值被赋给 result 变量。因此,控制台先打印了 finally 中的执行日志,随后才打印 result 的赋值结果。

这一现象再次验证了前文关于 finally 功能的描述:即便在 try 或 except 中执行了 return,finally 代码块依然会被执行。

既然 except 分支的行为已得到证实,那么 try 分支的行为又是如何呢?

def test():
    try:
        print('try_test')
        return 'try'
    except Exception as e:
        print(e)
    finally:
        print('通用异常捕获已完成')


result = test()
print(result)

# >>> 执行结果如下:
# >>> try_test
# >>> 通用异常捕获已完成
# >>> try

# >>> 得出了同样的 finally 必然触发性 的结论

进一步思考:此前示例中 finally 仅包含 print 语句,如果我们在 try、except 以及 finally 代码块中都使用 return 语句,最终返回的是哪个值?

def test():
    try:
        1 / 0
    except Exception as e:
        return e
    finally:
        return '通用异常捕获已完成'


result = test()
print(result)

# >>> 执行结果如下:
# >>> 通用异常捕获已完成

从执行结果来看,尽管 except 和 finally 中都定义了 return,且逻辑上先触发 except 的 return,但最终返回的值依然来自 finally 代码块中的 return。

虽然 except 分支存在 return,但由于 finally 中也使用了 return,程序最终选择执行 finally 中的 return 语句。由此得出一个关键结论:finally 中的 return 具有最高优先级,会覆盖 try 或 except 中的返回值。

try 语法中搭配 except 或 finally 的必要性探讨

参考以下示例代码。

def test():
    try:
        1 / 0
    finally:
        print('通用异常捕获已完成')


result = test()
print(result)

# >>> 执行结果如下:
# >>> 通用异常捕获已完成
# >>> Traceback (most recent call last):
# >>> 	File "D:\PycharmProjects\XXX\XXX.py", line 81, in <module>
# >>> 	    result = test()
# >>>   File "D:\PycharmProjects\XXX\XXX.py", line 76, in test
# >>>       1 / 0
# >>>   ZeroDivisionError: division by zero

可以看到,即使代码执行过程中产生报错,finally 代码块依然被正常执行。那么,在这种情况下直接使用 return 会发生什么?

def test():
    try:
        1 / 0
    finally:
        return '通用异常捕获已完成'


result = test()
print(result)

# >>> 执行结果如下:
# >>> 通用异常捕获已完成

结果显示,finally 代码块依然被执行,且此前出现的错误被忽略。这说明当 try 块发生异常时,程序会直接跳过异常处理逻辑,转而执行 finally 代码块。

这是 try 与 finally 直接组合的效果。但在实际工程开发中,通常建议结合 except 块,将异常类型或信息友好地打印出来,然后再执行 return,这样更利于调试和问题排查。

finally 的历史演变

在 Python 2.5 版本之前,finally 必须独立使用,不允许与 try 直接配合。直到 Python 2.5 版本,语法才演变为现今的 try-except-finally 结构。

如果未来有机会维护或运行较老版本的 Python 代码,看到此类语法结构无需感到意外。

本文关于 Python 异常处理中 finally 使用的详解到此结束。如需了解更多 Python 异常处理相关内容,请查阅本站往期文章或继续浏览后续系列教程,感谢大家的支持。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表