Python学习之异常中的finally使用详解


Posted in Python onMarch 16, 2022

今天我们来学习一下 异常语法 中的另一个成员 —> finally ; 通过学习 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 ,那么会返回谁的 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 或 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 的组合效果,不过在我们平时的工作中,还是希望 使用 try 配合 except 将 异常类型(信息) 友好的打印出来,再进行return 会更好。

finally 的历史

在 python 2.5 版本之前, finally 需要独立使用不可以和 try 进行配合,在 python 2.5 版本 之后才演变成了现在这个样子。

如果未来有机会使用较老版本的 python ,看到这样的情况,不要觉得奇怪。

到此这篇关于Python学习之异常中的finally使用详解的文章就介绍到这了,更多相关Python异常 finally内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python中selenium实现文件上传所有方法整理总结
Apr 01 Python
Python实现的下载网页源码功能示例
Jun 13 Python
神经网络python源码分享
Dec 15 Python
python中的字典操作及字典函数
Jan 03 Python
PyTorch CNN实战之MNIST手写数字识别示例
May 29 Python
深入了解Python枚举类型的相关知识
Jul 09 Python
解决安装python3.7.4报错Can''t connect to HTTPS URL because the SSL module is not available
Jul 31 Python
Python基于read(size)方法读取超大文件
Mar 12 Python
解决pycharm安装第三方库失败的问题
May 09 Python
Django 解决阿里云部署同步数据库报错的问题
May 14 Python
Python3以GitHub为例来实现模拟登录和爬取的实例讲解
Jul 30 Python
OpenCV实现机器人对物体进行移动跟随的方法实例
Nov 09 Python
Python实现抖音热搜定时爬取功能
Mar 16 #Python
Python3的进程和线程你了解吗
Mar 16 #Python
python的列表生成式,生成器和generator对象你了解吗
Mar 16 #Python
bat批处理之字符串操作的实现
Mar 16 #Python
一起来学习Python的元组和列表
Mar 13 #Python
python自动化测试之Selenium详解
python数字类型和占位符详情
Mar 13 #Python
You might like
PHP命名空间与自动加载机制的基础介绍
2019/08/25 PHP
求解开jscript.encode代码的asp函数
2007/02/28 Javascript
用js模拟JQuery的show与hide动画函数代码
2010/09/20 Javascript
让ie运行js时提示允许阻止内容运行的解决方法
2010/10/24 Javascript
JavaScript子窗口ModalDialog中操作父窗口对像
2012/12/11 Javascript
js iframe跨域访问(同主域/非同主域)分别深入介绍
2013/01/24 Javascript
JavaScript获取和设置CheckBox状态的简单方法
2013/07/05 Javascript
js中定义一个变量并判断其是否为空的方法
2014/05/13 Javascript
jquery用ajax方式从后台获取json数据后如何将内容填充到下拉列表
2015/08/26 Javascript
浅析JS中对函数function的理解(基础篇)
2016/10/14 Javascript
vue中用动态组件实现选项卡切换效果
2017/03/25 Javascript
利用vue.js实现被选中状态的改变方法
2018/02/08 Javascript
vue-cli初始化项目中使用less的方法
2018/08/09 Javascript
微信小程序template模板与component组件的区别和使用详解
2019/05/22 Javascript
JS实现悬浮球只在一侧滑动并且是横屏状态下
2020/08/19 Javascript
Python中让MySQL查询结果返回字典类型的方法
2014/08/22 Python
Python实现115网盘自动下载的方法
2014/09/30 Python
python getopt详解及简单实例
2016/12/30 Python
利用python打印出菱形、三角形以及矩形的方法实例
2017/08/08 Python
用TensorFlow实现lasso回归和岭回归算法的示例
2018/05/02 Python
在pycharm上mongodb配置及可视化设置方法
2018/11/30 Python
Ubuntu下升级 python3.7.1流程备忘(推荐)
2018/12/10 Python
PyQt5重写QComboBox的鼠标点击事件方法
2019/06/25 Python
深入了解Python iter() 方法的用法
2019/07/11 Python
对Python3中列表乘以某一个数的示例详解
2019/07/20 Python
python文档字符串(函数使用说明)使用详解
2019/07/30 Python
python实现图片二值化及灰度处理方式
2019/12/07 Python
微信浏览器取消缓存的方法
2015/03/28 HTML / CSS
Myprotein荷兰官网:欧洲第一运动营养品牌
2020/07/11 全球购物
大学生冰淇淋店商业计划书
2014/01/14 职场文书
列车长先进事迹材料
2014/01/25 职场文书
传承焦裕禄精神思想汇报2014
2014/09/10 职场文书
小学班主任事迹材料
2014/12/17 职场文书
银行客户经理岗位职责
2015/04/09 职场文书
警示教育片观后感
2015/06/17 职场文书
聘用合同范本
2015/09/21 职场文书