0. 引言

在编写Python程序时,有时我们不确定一段语句是否可以正确执行,因为如果发生错误,那么程序就会终止,这样对完整代码实现很不友好。我们希望可以程序可以根据不同的错误(异常)从而执行不同的语句,达到解决错误的效果。

1. try…except…else…finally…语句

1.1 语法

为了捕获异常,在编码过程中,我们可以简单使用 try/except 语句来捕捉异常,具体语法如下:

try:  # 尝试运行的语句(可能会发生异常,也可能不会发生异常)<语句>
except (异常类型1, 异常类型2, ...):  # 如果发生异常类型1时的操作<语句>
else:  # 如果没有发生异常的操作(可选)<语句>
finally:  # 不管有没有发生异常都会执行的操作<语句>

上面的代码实现了:通过监视 try 语句块中的错误,从而让 except 语句捕获异常信息并进行处理。因此,如果你不想在异常发生时结束你的程序,就需要在 try 语句块中捕获相应的异常。

1.2 例子

接下来,我们通过一个代码实例来具体了解一下 try...except 的用法。

1.2.1 出现异常

try:  # 尝试执行的语句(可能会发生异常,也可能不会发生异常)file = open("test.txt", "r")  # 以只读模式打开指定的文件file.write("这是一个测试文件,用于测试Python中的异常")except (IOError, ValueError) as e:  # 可以捕获不同类型的异常,实现有针对性处理问题print(f"捕获到的异常有 {e} ,但并不影响程序接下来的运行!")else:  # 如果没有发生异常print("没有发生异常!")finally:  # 不管有没有异常都会执行print("该代码块执行完毕!")# try代码块外的程序不会收到异常影响而中断
print("[try代码块外面的其他代码] try代码块只要捕获了异常就不会影响程序的运行(除非因为处理不好导致其他地方报错:joy:)!")"""捕获到的异常有 not writable ,但并不影响程序接下来的运行!该代码块执行完毕![try代码块外面的其他代码] try代码块只要捕获了异常就不会影响程序的运行(除非因为处理不好导致其他地方报错:joy:)!
"""

上述代码的意思是以可读模式打开一个 test.txt 文件,然后向文件中写入一段话:这是一个测试文件,用于测试Python中的异常! 因为文件是以可读模式打开的,所以没有写入权限,肯定会出错但因在 try 代码块中,肯定会被对应的IO错误类型捕获

1.2.2 没有异常

我们修改代码,以写模式打开文件再写入对应的语句,修改后代码如下:

try:  # 尝试执行的语句(可能会发生异常,也可能不会发生异常)file = open("test.txt", "w")  # 以只读模式打开指定的文件file.write("这是一个测试文件,用于测试Python中的异常")except (IOError, ValueError) as e:  # 可以捕获不同类型的异常,实现有针对性处理问题print(f"捕获到的异常有 {e} ,但并不影响程序接下来的运行!")else:  # 如果没有发生异常print("没有发生异常!")finally:  # 不管有没有异常都会执行print("该代码块执行完毕!")# try代码块外的程序不会收到异常影响而中断
print("[try代码块外面的其他代码] try代码块只要捕获了异常就不会影响程序的运行(除非因为处理不好导致其他地方报错:joy:)!")"""没有发生异常!该代码块执行完毕![try代码块外面的其他代码] try代码块只要捕获了异常就不会影响程序的运行(除非因为处理不好导致其他地方报错:joy:)!
"""

1.3 try的工作原理

try 的工作原理是,当开始一个 try 语句后,python 就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try 子句先执行,接下来会发生什么依赖于执行时是否出现异常。大致的情况可以分为两种,一种是触发了异常,另一种是没有触发异常,具体表现如下:

  1. 如果当 try 后的代码里发生了异常,python 就跳回到 try 并执行第一个匹配该异常的 except 子句,异常处理完毕,控制流就通过整个 try 语句。

  2. 如果在 try 后的代码里没有发生异常,python将执行else语句后的语句,然后控制流通过整个try语句。

其实,上面的代码实例很好的覆盖了这两种情况。

2. 主动抛出异常 —— raise

我们从来都是想方设法地让程序正常运行,为什么还要手动设置异常呢?首先要分清楚程序发生异常程序执行错误,它们完全是两码事:

  • 程序由于错误导致的运行异常,是需要程序员想办法解决的 —— 一般使用try...except...语句或者直接debug
  • 但还有一些异常,是程序正常运行的结果,比如用 raise 手动引发的异常。

2.1 语法

raise 语句的基本语法格式为:

raise [exceptionName [(reason)]]

其中, exceptionNamereason 为均可选参数,前者的作用是指定抛出的异常名称,后者为异常信息的相关描述

  • 如果可选参数全部省略,则 raise 会把当前错误原样抛出
  • 如果仅省略 (reason),则在抛出异常时,将不附带任何的异常描述信息

也就是说,raise 语句有如下三种常用的用法:

  • raise:单独一个 raise。该语句引发当前上下文中捕获的异常(比如在 except 块中),或默认引发 RuntimeError 异常
  • raise exceptionName:raise 后带一个异常类名称,表示引发执行类型的异常。
  • raise exceptionName(reason):在引发指定类型的异常的同时,附带异常的描述信息。

显然,每次执行 raise 语句,都只能引发一次执行的异常。首先,我们来测试一下以上 3 种 raise 的用法:

>>> # 1. 单独一个raise
>>> raise
Traceback (most recent call last):File "<stdin>", line 1, in <module>
RuntimeError: No active exception to reraise>>> # 2. raise exceptionName
>>> raise ZeroDivisionError
Traceback (most recent call last):File "<stdin>", line 1, in <module>
ZeroDivisionError>>> raise NoArgumentsError
Traceback (most recent call last):File "<stdin>", line 1, in <module>
NameError: name 'NoArgumentsError' is not defined  # exception需要符合规定,不行自己乱写>>> NoArgumentsError = "没有参数异常"
>>> raise NoArgumentsError
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: exceptions must derive from BaseException  # exception需要符合规定,不行自己乱写>>> raise Exception("NoArgumentsError")
Traceback (most recent call last):File "<stdin>", line 1, in <module>
Exception: NoArgumentsError>>> # 3. raise exceptionName(reason)
>>> raise ZeroDivisionError("除零错误!")
Traceback (most recent call last):File "<stdin>", line 1, in <module>
ZeroDivisionError: 除零错误!

2.2 使用raise的目的

我们手动让程序引发异常,很多时候并不是为了让其崩溃。事实上,raise 语句引发的异常通常用 try except (else finally)异常处理结构来捕获并进行处理。例如:

try:num = input("请输入一个数字:")if not num.isdigit():raise ValueError(f"输入的{num}不是一个数字!")else:print(f"输入的数字为:{num}")
except ValueError as e:  # 捕获 ValueError 并as为eprint(f"触发[{e}]异常")"""请输入一个数字:leovin触发[输入的leovin不是一个数字!]异常
"""

可以看到,当用户输入的不是数字时,程序会进入 if 判断语句,并执行 raise 引发 ValueError 异常。但由于其位于 try 块中,因为 raise 抛出的异常会被 try 捕获,并由 except 块进行处理。

因此,虽然程序中使用了 raise 语句引发异常,但程序的执行是正常的,手动抛出的异常经过合适的处理并不会导致程序崩溃。

2.3 raise默认引发的异常

当在没有引发过异常的程序使用无参的 raise 语句时,它默认引发的是 RuntimeError 异常。例如:

try:num = input("请输入一个数字:")if not num.isdigit():raiseelse:print(f"输入为: {num}")
except RuntimeError as e:print(f"异常[{e}]触发")"""请输入一个数字:leovin异常[No active exception to reraise]触发
"""

2.4 不指定except需捕获的异常

try:num = input("请输入一个数字:")if not num.isdigit():raiseelse:print(f"输入为: {num}")
except:print(f"异常触发")  # 但这样我们就不知道具体是什么异常发生了!"""请输入一个数字:leovin异常触发
"""

3. 异常的类型

异常名称 描述
BaseException 所在异常的基类
Exception 常规错误的基类
SystemExit 解释器请求退出异常
KeyboardInterrupt 用户中断执行(通常用的是Ctrl + C)
StopIteration 迭代器没有更多的值
GeneratorExit 生成器发生异常并退出
StandardError 所有的内建(built-in)标准异常的基类
ArithmeticError 所有数值计算错误的基类
FloatingPointError 浮点计算错误
OverflowError 数值运算超出最大限制(堆栈溢出错误)
ZeroDivisionError 除零错误/取模为0错误
AssertionError 断言语句条件不满足错误
AttributeError 对象属性错误(一般为没有的属性被调用)
EOFError 没有内建输入,达到EOF标记
EnvironmentError 操作系统错误的基类
IOError 输入/输出操作失败错误
OSError 操作系统错误
WindowsError 系统调用错误
ImportError import失败
LookupError 无效数据查询的基类
IndexError 没有的索引被引用
KeyError 没有的key被调用
MemoryError 内存溢出错误(对Python解释器来说并不是致命错误)
NameError 未声明/初始化对象(没有该属性)被调用时的错误
UnboundLocalError 访问未初始化的local变量(局部变量)
ReferenceError 弱引用(weak reference):试图访问已经被回收的对象
RuntimeError 一般的运行时错误
NotImplementedError 调用尚未实现的方法
SyntaxError Python语法错误
IndentationError 缩进错误
TabError Tab和空格混用时的错误
SystemError 一般的解释器系统错误
TypeError 数据类型错误
ValueError 传入无效值时发生的错误
UnicodeError Unicode相关的错误
UnicodeDecodeError Unicode解码时发生的错误
UnicodeEncodeError Unicode编码时发生的错误
UnicodeTranslateError Unicode转换时发生的错误
Warning 警告的基类
DeprecationWarning 使用弃用特征(方法)时的警告
FutureWarning 构造将来语义会有改变的警告
OverflowWarning 自动提升为长整型 (long) 的警告
PendingDeprecationWarning 调用即将(马上)废弃特性(方法)的警告
RuntimeWaring 调用可疑的运行时行为(runtime behavior)时发出的警告
SyntaxWarning 可疑的语法警告
UserWarning 用户代码生成的警告

4. 异常的层次关系(hierarchical structure)

#mermaid-svg-gONgym26JpujktvA {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-gONgym26JpujktvA .error-icon{fill:#552222;}#mermaid-svg-gONgym26JpujktvA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gONgym26JpujktvA .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-gONgym26JpujktvA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gONgym26JpujktvA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gONgym26JpujktvA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gONgym26JpujktvA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gONgym26JpujktvA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gONgym26JpujktvA .marker.cross{stroke:#333333;}#mermaid-svg-gONgym26JpujktvA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gONgym26JpujktvA .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gONgym26JpujktvA .cluster-label text{fill:#333;}#mermaid-svg-gONgym26JpujktvA .cluster-label span{color:#333;}#mermaid-svg-gONgym26JpujktvA .label text,#mermaid-svg-gONgym26JpujktvA span{fill:#333;color:#333;}#mermaid-svg-gONgym26JpujktvA .node rect,#mermaid-svg-gONgym26JpujktvA .node circle,#mermaid-svg-gONgym26JpujktvA .node ellipse,#mermaid-svg-gONgym26JpujktvA .node polygon,#mermaid-svg-gONgym26JpujktvA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gONgym26JpujktvA .node .label{text-align:center;}#mermaid-svg-gONgym26JpujktvA .node.clickable{cursor:pointer;}#mermaid-svg-gONgym26JpujktvA .arrowheadPath{fill:#333333;}#mermaid-svg-gONgym26JpujktvA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gONgym26JpujktvA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gONgym26JpujktvA .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-gONgym26JpujktvA .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-gONgym26JpujktvA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gONgym26JpujktvA .cluster text{fill:#333;}#mermaid-svg-gONgym26JpujktvA .cluster span{color:#333;}#mermaid-svg-gONgym26JpujktvA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gONgym26JpujktvA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

object
BaseException
Exception
ArithmeicError
EnvironmentError
EOFError
LookupError
ValueError
IOError
OSError
IndexError
KeyError

参考

  1. http://c.biancheng.net/view/2360.html
  2. https://www.jb51.net/article/220448.htm

Python中的异常、try、except、finally、raise语法以及示例相关推荐

  1. Python基础之:Python中的异常和错误

    文章目录 简介 Python中的内置异常类 语法错误 异常 异常处理 抛出异常 异常链 自定义异常 finally 简介 和其他的语言一样,Python中也有异常和错误.在 Python 中,所有异常 ...

  2. 在Python中捕捉异常

    在Python中捕捉异常 在Python中,可以使用try语句处理异常. 可能引发异常的关键操作放在try子句中,并且将处理异常的代码编写在except子句中. 捕获异常后,我们将执行什么操作取决于我 ...

  3. Python中获取异常(try Exception)信息

    Python中获取异常(try Exception)信息 参考文章: (1)Python中获取异常(try Exception)信息 (2)https://www.cnblogs.com/hixiao ...

  4. python读取json数据格式问题_浅谈Python中的异常和JSON读写数据的实现

    异常可以防止出现一些不友好的信息返回给用户,有助于提升程序的可用性,在java中通过try ... catch ... finally来处理异常,在Python中通过try ... except .. ...

  5. python 忽略 异常_如何忽略Python中的异常?

    python 忽略 异常 什么是例外? (What is an Exception?) An exception is an event, which occurs during the execut ...

  6. 【华为云技术分享】Python 中的异常和错误

    [摘要] 异常就是程序运行时发生错误的信号,在python中,错误触发的异常如下 异常和错误 第一:程序中难免出现错误,而错误分成两种 1.语法错误(这种错误,根本过不了python解释器的语法检测, ...

  7. python中什么是异常_一文教你读懂 Python 中的异常信息

    在写 Python 代码的时候,当代码中出现错误,会在输出的时候打印 Traceback  错误信息,很多初学者看到那一堆错误信息,往往都会处于懵逼状态,脑中总会冒出一句,这都是些啥玩意.如果你是第一 ...

  8. python中的异常分类_列举 5 个 Python 中的异常类型以及其含义【面试题详解】

    今天爱分享给大家带来列举 5 个 Python 中的异常类型以及其含义[面试题详解],希望能够帮助到大家. BaseException +-- SystemExit +-- KeyboardInter ...

  9. python中formatter的用法_Python pyplot.FuncFormatter方法代码示例

    本文整理汇总了Python中matplotlib.pyplot.FuncFormatter方法的典型用法代码示例.如果您正苦于以下问题:Python pyplot.FuncFormatter方法的具体 ...

最新文章

  1. 查看服务器硬盘负载——判断硬盘是否为瓶颈
  2. DHCP服务器的搭建
  3. element ui input视图没刷新_聊聊前端 UI 组件:组件体系
  4. nodejs 实践:express 最佳实践(五) connect解析
  5. CSAPP(8):系统级IO
  6. Ubuntu16.04安装CDH
  7. [转载]如何在只能力加载的有限元程序里面实现按位移加载
  8. CodeSmith实用技巧(八):生成的代码输出到文件中
  9. 嗓子痛引发大抢救!33岁程序员的垂死经历,为所有人敲响警钟!
  10. Markdown语法--整理
  11. 【干货】华为-智能世界2030:构建万物互联的智能世界
  12. 语音识别软件、语音识别平台和语音识别技术
  13. c语言构成循环结构的是,C语言循环结构选择题
  14. Chapter 5 Blood Type——15
  15. JqueryEasyUI $.Parser
  16. 小型微型计算机投稿流程,小型微型计算机系统
  17. 利用ptrace设计一个简单的debugger调试器
  18. 微信动态表情保存到手机相册
  19. 你想成为阿里巴巴的一名数据工程师吗?以下的应聘要求你得好好看了
  20. 贷款行业怎样运用运营商数据找精准客户?

热门文章

  1. 每次进入命令需要重新source的解决方法
  2. 时间在流逝——上还是不上大学?
  3. [需求管理-4]:需求分析全过程:需求分析+资源评估+项目计划
  4. Fully Attentional Network for Semantic Segmentation
  5. backpressure 背压介绍
  6. JEM software ticket45:Console output error of nQP when LCU level rate control is enabled
  7. AutoLisp从入门到放弃(十七)
  8. 解决ORA-28000:the account is locked,解锁oracle用户
  9. 范式存在定理及其证明
  10. Ubuntu18.04使用RPLIDAR A2M12雷达出错的解决办法