中raise抛出异常_Python 异常处理知识点汇总,五分钟就能学会 !

异常处理在任何一门编程语言里都是值得关注的一个话题,良好的异常处理可以让你的程序更加健壮,清晰的错误信息更能帮助你快速修复问题。在Python中,和不分高级语言一样,使用了try/except/finally语句块来处理异常,如果你有其他编程语言的经验,实践起来并不难。

什么是异常?

1.错误

从软件方面来说,错误是语法或是逻辑上的。错误是语法或是逻辑上的。

语法错误指示软件的结构上有错误,导致不能被解释器解释或编译器无法编译。这些些错误必须在程序执行前纠正。

当程序的语法正确后,剩下的就是逻辑错误了。逻辑错误可能是由于不完整或是不合法的输入所致;

在其它情况下,还可能是逻辑无法生成、计算、或是输出结果需要的过程无法执行。这些错误通常分别被称为域错误和范围错误。

当python检测到一个错误时,python解释器就会指出当前流已经无法继续执行下去。这时候就出现了异常。

2.异常

对异常的最好描述是:它是因为程序出现了错误而在正常控制流以外采取的行为。

这个行为又分为两个阶段:首先是引起异常发生的错误,然后是检测(和采取可能的措施)阶段。

第一阶段是在发生了一个异常条件(有时候也叫做例外的条件)后发生的。

只要检测到错误并且意识到异常条件,解释器就会发生一个异常。引发也可以叫做触发,抛出或者生成。解释器通过它通知当前控制流有错误发生。

python也允许程序员自己引发异常。无论是python解释器还是程序员引发的,异常就是错误发生的信号。

当前流将被打断,用来处理这个错误并采取相应的操作。这就是第二阶段。

对于异常的处理发生在第二阶段,异常引发后,可以调用很多不同的操作。

可以是忽略错误(记录错误但不采取任何措施,采取补救措施后终止程序。)或是减轻问题的影响后设法继续执行程序。

所有的这些操作都代表一种继续,或是控制的分支。关键是程序员在错误发生时可以指示程序如何执行。

python用异常对象(exception object)来表示异常。遇到错误后,会引发异常。

如果异常对象并未被处理或捕捉,程序就会用所谓的回溯(traceback)终止执行

异常处理

捕捉异常可以使用try/except语句。

try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。

如果你不想在异常发生时结束你的程序,只需在try里捕获它。

语法:

以下为简单的try....except...else的语法:

c9330d221ce161563f77d607f2098430.png

Try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。

  1. 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
  2. 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
  3. 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。

使用except而不带任何异常类型

你可以不带任何异常类型使用except,如下实例:

a3c16e77126f5671e51700202779bf1f.png


以上方式try-except语句捕获所有发生的异常。但这不是一个很好的方式,我们不能通过该程序识别出具体的异常信息。因为它捕获所有的异常。

使用except而带多种异常类型

你也可以使用相同的except语句来处理多个异常信息,如下所示:

c0e4cb6e70d5a575d015375da1e2fcbe.png

try-finally 语句

try-finally 语句无论是否发生异常都将执行最后的代码。

7cabb4c49bb404bb53df0b826facd113.png

当在try块中抛出一个异常,立即执行finally块代码。

finally块中的所有语句执行后,异常被再次触发,并执行except块代码。

参数的内容不同于异常。

下面来看一个实例:

7a5b285d8d0765eae32a4bd689184ba6.png

点击查看大图

总结如下:

  1. except语句不是必须的,finally语句也不是必须的,但是二者必须要有一个,否则就没有try的意义了。
  2. except语句可以有多个,Python会按except语句的顺序依次匹配你指定的异常,如果异常已经处理就不会再进入后面的except语句。
  3. except语句可以以元组形式同时指定多个异常,参见实例代码。
  4. except语句后面如果不指定异常类型,则默认捕获所有异常,你可以通过logging或者sys模块获取当前异常。
  5. 如果要捕获异常后要重复抛出,请使用raise,后面不要带任何参数或信息。
  6. 不建议捕获并抛出同一个异常,请考虑重构你的代码。
  7. 不建议在不清楚逻辑的情况下捕获所有异常,有可能你隐藏了很严重的问题。
  8. 尽量使用内置的异常处理语句来 替换try/except语句,比如with语句,getattr()方法。

经验案例

传递异常 re-raise Exception
捕捉到了异常,但是又想重新引发它(传递异常),使用不带参数的raise语句即可:

d82cf8a1aa6e3794b20f428422b4283f.png

在Python2中,为了保持异常的完整信息,那么你捕获后再次抛出时千万不能在raise后面加上异常对象,否则你的trace信息就会从此处截断。以上是最简单的重新抛出异常的做法。

还有一些技巧可以考虑,比如抛出异常前对异常的信息进行更新。

2d1fff0fb2c1ec8ba0c3151ae92b41fc.png

如果你有兴趣了解更多,建议阅读这篇博客。

  • http://www.ianbicking.org/blog/2007/09/re-raising-exceptions.html

Python3对重复传递异常有所改进,你可以自己尝试一下,不过建议还是同上。

Exception 和 BaseException

当我们要捕获一个通用异常时,应该用Exception还是BaseException?我建议你还是看一下 官方文档说明,这两个异常到底有啥区别呢? 请看它们之间的继承关系。

611b9af6b16fb25e3c19c6c7098051fb.png

从Exception的层级结构来看,BaseException是最基础的异常类,Exception继承了它。BaseException除了包含所有的Exception外还包含了SystemExit,KeyboardInterrupt和GeneratorExit三个异常。

有此看来你的程序在捕获所有异常时更应该使用Exception而不是BaseException,因为另外三个异常属于更高级别的异常,合理的做法应该是交给Python的解释器处理。

except Exception as e和 except Exception, e

代码示例如下:

8d722debb025908c9a729fb766deb26f.png

在Python2的时代,你可以使用以上两种写法中的任意一种。在Python3中你只能使用第一种写法,第二种写法被废弃掉了。第一个种写法可读性更好,而且为了程序的兼容性和后期移植的成本,请你也抛弃第二种写法。

raise “Exception string”

把字符串当成异常抛出看上去是一个非常简洁的办法,但其实是一个非常不好的习惯。

30513a27259a9e7343860ea491118df6.png

上面的语句如果抛出异常,那么会是这样的:

f451e59ab957b812dd79939c5f64c977.png

这在Python2.4以前是可以接受的做法,但是没有指定异常类型有可能会让下游没办法正确捕获并处理这个异常,从而导致你的程序挂掉。简单说,这种写法是是封建时代的陋习,应该扔了。

使用内置的语法范式代替try/except

Python 本身提供了很多的语法范式简化了异常的处理,比如for语句就处理的StopIteration异常,让你很流畅地写出一个循环。

with语句在打开文件后会自动调用finally中的关闭文件操作。我们在写Python代码时应该尽量避免在遇到这种情况时还使用try/except/finally的思维来处理。

dd6a7d756fc7b7fdbbdf759a313376ac.png

再比如,当我们需要访问一个不确定的属性时,有可能你会写出这样的代码:

df93e11f1e1246af8eba5d0ad568130b.png

其实你可以使用更简单的getattr()来达到你的目的。

91d821213926e941a2c686a2dc373a43.png

最佳实践

最佳实践不限于编程语言,只是一些规则和填坑后的收获。

1.只处理你知道的异常,避免捕获所有异常然后吞掉它们。

2.抛出的异常应该说明原因,有时候你知道异常类型也猜不出所以然的。

3.避免在catch语句块中干一些没意义的事情。

4.不要使用异常来控制流程,那样你的程序会无比难懂和难维护。

5.如果有需要,切记使用finally来释放资源。

6如果有需要,请不要忘记在处理异常后做清理工作或者回滚操作。

异常速查表

807a0e28068ce79c24b5caa20c6b0f54.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/563086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

easyexcel多个sheet导入_Java中Easypoi实现excel多sheet表导入导出功能

Easypoi简化了开发中对文档的导入导出实现,并不像poi那样都要写大段工具类来搞定文档的读写。第一步引入Easypoi依赖cn.afterturneasypoi-spring-boot-starter4.2.0Easypoi的注解使用说明(存留查看即可)第二步定义对应表格头数据对象实体类(注解的使用可以查阅上面的…

mysql 严格模式_MySQL 开启/关闭 严格模式(Strict Mode)

[广告:最高 2000 红包]阿里云服务器、主机等产品通用,可叠加官网常规优惠使用 | 限时领取查看 Mysql 是否开启严格模式:打开 MySQL 配置文件 my.cnf(windows为my.ini)。搜索 sql-mode 如果搜索不到就代表 非严格模式 。搜索到了就代表开启了严…

mysql 导入日期 0000_解决Excel导入MySQL日期为0000-00-00

最近在为客户做一个库存升级改造的项目,之前客户的数据管理全部是在Excel中操作,估计以前也是没有意识到数据量变大以后,工作会变得如此困难,基本上处于一个无法操作的程度了。于是我们将旧版本的Excel表格格式化以后,…

关于mysql优化_关于MySQL优化的几点总结

前言现如今,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显。所以,我整理了MySQL优化的几点建议,希望这些优化技巧对您有用,总结不到的,欢迎大家补充。SQL执行慢的原因网络速度慢&am…

ubuntu忘记mysql密码_ubuntu 忘记mysql 密码解决方法

一段时间没有用mysql数据库,今天突然需要使用,结果忘记密码,google了下找到的解决方法,就顺便记录下,下次碰到就不需要这么麻烦了1、输入命令 cat /etc/mysql/debian.cnf2、使用账号 debian-sys-maint 账号登录mysql密…

navicat mysql创建表_Navicat for MySQL如何创建数据表

Navicat for MySQL是针对MySQL数据库管理而研发的管理工具,创建数据表是其最基本操作,本教程将详解Navicat for MySQL创建数据表的方法。 步骤一:新建连接 运行Navicat数据库管理工具,连接本地数据库。点击左上角“文件”或者工具栏“连接”图标,创建自己的数据库连接。Na…

mysql-5.1.73-8.el6_在centos中安装mysql详细步骤说明

Last login: Sun Dec 24 04:55:59 20171、安装依赖[rootnode001 ~]# yum install -y perlLoaded plugins: fastestmirrorLoading mirror speeds from cached hostfilebase | 3.7 kB 00:00extras | 3.4 kB 00:00updates | 3.4 kB 00:00Setting up Install ProcessPackage 4:perl…

lte盲重定向_LTE重选、切换、重定向的区别

【资料名称】:LTE重选、切换、重定向的区别【资料作者】:A【资料日期】:20150916【资料语言】:中文【资料格式】:DOC/DOCX【资料目录和简介】:这里主要简单阐述了LTE系统的小区重选、切换、重定向的区别小区…

冯乐乐 unity_Unity常用矩阵运算的推导补遗——切线空间

在上一篇文章中,我写了一些关于Unity中各个坐标空间及其转换矩阵是如何得到的,说实在的,我是那种“记忆需要依靠外部装置存储”类、如同《攻壳机动队》的电子脑一样的人,每次遇到问题了再去对着笔记慢慢翻找才是我的风格&#xff…

mysql 字段类型设计_Mysql字段类型设计相关问题!-阿里云开发者社区

Mysql是以文件存储在我们的系统的硬盘上面,那么(1)当我们读取写入的时候就会有磁盘IO的问题(2)当我们存储的数据是以页单位存储,而且每页的大小是16K,那么我们要尽可能的让我们的一页数据存放的更多。表结构宽度不要太大,也就是列…

mysql保存时乱码了_MySQL保存中文乱码的原因和解决办法

(3)MySQL的字符集设置。这个是重点了,一般都是在这里搞错而出现了mysql乱码。mysql编码设置可以分为三种设置:数据库的编码、表的编码、和字段的编码。a、数据库的编码:在sqlyog工具中操作把,右击数据库点击更改数据库&#xff0c…

python中convert函数用法_Python Pandas DataFrame.tz_convert用法及代码示例

Pandas DataFrame是带有标签轴(行和列)的二维大小可变的,可能是异构的表格数据结构。算术运算在行和列标签上对齐。可以将其视为Series对象的dict-like容器。这是 Pandas 的主要数据结构。Pandas DataFrame.tz_convert()用于将tz-aware轴转换为目标时区。用法&#…

python偶数个数_python基础

标识符命名规则开发中,通常约定俗称遵守如下规则:删除变量和垃圾回收机制可以通过del语句删除不在使用的变量a 123 del a #删除了栈,没有删除堆链式赋值xy123 相当于 x123;y123系列解包赋值系列数据赋值给对应相同…

keyshot怎么让物体发光_户外发光字的防水措施怎么做,不亮了怎么修。

户外发光字的防水措施与维修发光字大多是安装在户外的,因此会受到热晒、雨淋、寒冻等因素的影响,这些因素都会加速LED发光字的老化,从而使LED发光字进水老化。那么,该怎么防止这种情况呢?一、在每个广告字的笔画的最下方&#xf…

mysql删除员工_数据库删除职工信息

《数据库技术原理与应用教程第2版》——1.4数据管理本节书摘来自华章出版社《数据库技术原理与应用教程第2版》一书中的第1章,第1.4节,作者 徐洁磐 操凤萍  ,更多章节内容可以访问云栖社区“华章计算机”公众号查看。1.4数据管理人类社会有着…

手撕包菜 mysql_手撕包菜搭建

概述最近做了两件事,一件事就是买了块1t硬盘,第二件事就是买了个百度云会员,无奈找不到资源下载,那就没办法了,搭建一个磁力链接搜索引擎来爬去链接,然后去找资源。说道磁力链接搜索引擎,最好的…

word流程图怎么使箭头对齐_word 流程图 怎么把箭头对整齐啊?

word里画流程图把箭bai头画直du,可通过shift键实现画出zhi垂直或水平的直箭头。方法步dao骤如下:回1、打开需要答操作的WORD文档,选中需要画出箭头的流程图框图,点解绘图工具中的“排列对齐”,然后选中“左右居中”对齐。2、在插入形状中找到并点击箭头,使用箭头形状工具…

java商品管理系统_【Java Web】简易商品信息管理系统——首个Web项目

正文之前在学习了一段时间的Java Web的内容之后,当然需要有个项目来练练手,我相信大多数人的首选项目都是信息管理系统吧,所以我选择了商品信息管理系统目前项目源码已全部上传至GitHub,欢迎大家来fork —— 商品信息管理系统正文…

java 向上舍入_介绍Java的大数类(BigDecimal)和八种舍入模式

1.BigDecimal简介BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale) 组成。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负scale 次幂。因此,BigDecimal表示的数值是(unscaledValue 10-s…

java spring mvc_java spring mvc 全注解

本人苦逼学生一枚,马上就要毕业,面临找工作,实在是不想离开学校.在老师的教导下学习了spring mvc ,配置文件实在繁琐,因此网上百度学习了spring mvc 全注解方式完成spring的装配工作;废话不多说了上干货,其实我也没怎么理解不过简单的运行了一个spring mvc 全注解项目,也不能说…