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

什么是异常?

1.错误

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

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

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

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

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

2.异常

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

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

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

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

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

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

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

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

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

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

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

异常处理

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

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

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

语法:

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

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

如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。

如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。

如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。

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

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

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

使用except而带多种异常类型

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

try-finally 语句

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

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

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

参数的内容不同于异常。

下面来看一个实例:

总结如下:

except语句不是必须的,finally语句也不是必须的,但是二者必须要有一个,否则就没有try的意义了。

except语句可以有多个,Python会按except语句的顺序依次匹配你指定的异常,如果异常已经处理就不会再进入后面的except语句。

except语句可以以元组形式同时指定多个异常,参见实例代码。

except语句后面如果不指定异常类型,则默认捕获所有异常,你可以通过logging或者sys模块获取当前异常。

如果要捕获异常后要重复抛出,请使用raise,后面不要带任何参数或信息。

不建议捕获并抛出同一个异常,请考虑重构你的代码。

不建议在不清楚逻辑的情况下捕获所有异常,有可能你隐藏了很严重的问题。

尽量使用内置的异常处理语句来 替换try/except语句,比如with语句,getattr()方法。

经验案例

传递异常 re-raise Exception

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

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

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

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

Exception 和 BaseException

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

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

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

except Exception as e和 except Exception, e

代码示例如下:

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

raise “Exception string”

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

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

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

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

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

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

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

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

最佳实践

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

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

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

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

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

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

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

异常速查表

如果我还有那点没有总结出来,欢迎留言评论!

python异常处理语句编程题_一篇文章让你掌握Python异常处理所有知识点,记得收藏...相关推荐

  1. python人脸识别防小偷_一篇文章带你了解Python 人脸识别有多简单

    今天的Python学习教程给大家介绍一个世界上最简练的人脸辨认库 face_recognition,你可以应用 Python 和命令行工具进行提取.辨认.操作人脸. 基于业内领先的 C++ 开源库 d ...

  2. python下载电影天堂视频_一篇文章教会你利用Python网络爬虫获取电影天堂视频下载链接...

    点击上方"IT共享之家",进行关注 回复"资料"可获赠Python学习福利 [一.项目背景] 相信大家都有一种头疼的体验,要下载电影特别费劲,对吧?要一部一部的 ...

  3. python下载电影天堂视频教程_一篇文章教会你利用Python网络爬虫获取电影天堂视频下载链接|python基础教程|python入门|python教程...

    https://www.xin3721.com/eschool/pythonxin3721/ [一.项目背景] 相信大家都有一种头疼的体验,要下载电影特别费劲,对吧?要一部一部的下载,而且不能直观的知 ...

  4. 如何写一个python程序浏览淘宝_一篇文章教会你用Python爬取淘宝评论数据(写在记事本)...

    [一.项目简介] 本文主要目标是采集淘宝的评价,找出客户所需要的功能.统计客户评价上面夸哪个功能多,比如防水,容量大,好看等等. [二.项目准备工作] 1. 准备Pycharm,下载安装等,可以参考这 ...

  5. python 抖音文案提取_一篇文章教会你用Python抓取抖音app热点数据!

    今天给大家分享一篇简单的安卓app数据分析及抓取方法.以抖音为例,我们想要抓取抖音的热点榜数据. 要知道,这个数据是没有网页版的,只能从手机端下手. 首先我们要安装charles抓包APP数据,它是一 ...

  6. python 抖音文案提取_一篇文章教会你用Python抓取抖音app热点数据

    今天给大家分享一篇简单的安卓app数据分析及抓取方法.以抖音为例,我们想要抓取抖音的热点榜数据. 要知道,这个数据是没有网页版的,只能从手机端下手. 首先我们要安装charles抓包APP数据,它是一 ...

  7. python网络爬虫_一篇文章教会你利用Python网络爬虫获取穷游攻略

    点击上方"IT共享之家",进行关注 回复"资料"可获赠Python学习福利 [一.项目背景] 穷游网提供原创实用的出境游旅行指南.攻略,旅行社区和问答交流平台, ...

  8. python爬淘宝app数据_一篇文章教会你用Python爬取淘宝评论数据(写在记事本)

    [一.项目简介] 本文主要目标是采集淘宝的评价,找出客户所需要的功能.统计客户评价上面夸哪个功能多,比如防水,容量大,好看等等. [二.项目准备工作] 准备Pycharm,下载安装等,可以参考这篇文章 ...

  9. python人脸识别实验报告总结_一篇文章带你了解Python 人脸识别有多简单

    原标题:一篇文章带你了解Python 人脸识别有多简单 今天的Python学习教程给大家介绍一个世界上最简洁的人脸识别库 face_recognition,你可以使用 Python 和命令行工具进行提 ...

最新文章

  1. 为11.2.0.2 Grid Infrastructure添加节点
  2. 大数据互联网架构阶段 Spring框架导致的406错误
  3. 分布式文件系统研究-测试-搭建测试环境
  4. 机器学习算法Python实现:word2vec 求词语相似度
  5. mysql导入source数据库sql的C++实现和封装
  6. Qt工作笔记-保存textEdit中的数据,并自动打开文件
  7. ethtool -g rx_魔兽怀旧服:黑G团避坑指南
  8. JavaScript正则表达式使用详解
  9. django的orm获取字段去重值
  10. windows补丁下载地址
  11. rk3568 android 11 更换系统签名
  12. 向量数量积公式_向量的数量积公式大全
  13. Mysql数据库高可用方案
  14. 使用git命令提交远程github仓库的时候提示rejected(拒绝)解决办法
  15. CDN是什么?CDN有哪些用处?
  16. 北京的购车摇号新政的概率分析
  17. linux实用的磁盘大文件及大文件夹查找命令
  18. 计算机主机如何控制计算机室,电脑远程控制怎么弄?电脑弄远程控制功能的方法...
  19. Linux下安装EPSON L310打印机驱动
  20. Springboot 中的Redis 事务使用

热门文章

  1. 深度解析 Lucene 轻量级全文索引实现原理
  2. 炸裂!MySQL 82 张图带你飞!
  3. 百度程序员发现自己一直无私帮助的女下属其男友在背后教她利用自己完成工作!自己却为了帮她天天加班,冷落自己老婆。...
  4. UML科普文,一篇文章掌握14种UML图
  5. 你必须会的 JDK 动态代理和 CGLIB 动态代理
  6. 深入理解 Java 虚拟机(第二弹) - 常用 vm 参数分析
  7. 利用Kafka和Cassandra构建实时异常检测实验
  8. Angular 表单验证类库 ngx-validator 1.0 正式发布
  9. 推荐8个特别实用、功能强大的软件,解决痛点需求
  10. 社区拼团软件系统开发为什么这么火热?