Python中的异常、try、except、finally、raise语法以及示例
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 子句先执行,接下来会发生什么依赖于执行时是否出现异常。大致的情况可以分为两种,一种是触发了异常,另一种是没有触发异常,具体表现如下:
如果当 try 后的代码里发生了异常,python 就跳回到 try 并执行第一个匹配该异常的 except 子句,异常处理完毕,控制流就通过整个 try 语句。
如果在 try 后的代码里没有发生异常,python将执行else语句后的语句,然后控制流通过整个try语句。
其实,上面的代码实例很好的覆盖了这两种情况。
2. 主动抛出异常 —— raise
我们从来都是想方设法地让程序正常运行,为什么还要手动设置异常呢?首先要分清楚程序发生异常和程序执行错误,它们完全是两码事:
- 程序由于错误导致的运行异常,是需要程序员想办法解决的 —— 一般使用
try...except...
语句或者直接debug - 但还有一些异常,是程序正常运行的结果,比如用 raise 手动引发的异常。
2.1 语法
raise 语句的基本语法格式为:
raise [exceptionName [(reason)]]
其中, exceptionName
和reason
为均可选参数,前者的作用是指定抛出的异常名称,后者为异常信息的相关描述。
- 如果可选参数全部省略,则 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)
参考
- http://c.biancheng.net/view/2360.html
- https://www.jb51.net/article/220448.htm
Python中的异常、try、except、finally、raise语法以及示例相关推荐
- Python基础之:Python中的异常和错误
文章目录 简介 Python中的内置异常类 语法错误 异常 异常处理 抛出异常 异常链 自定义异常 finally 简介 和其他的语言一样,Python中也有异常和错误.在 Python 中,所有异常 ...
- 在Python中捕捉异常
在Python中捕捉异常 在Python中,可以使用try语句处理异常. 可能引发异常的关键操作放在try子句中,并且将处理异常的代码编写在except子句中. 捕获异常后,我们将执行什么操作取决于我 ...
- Python中获取异常(try Exception)信息
Python中获取异常(try Exception)信息 参考文章: (1)Python中获取异常(try Exception)信息 (2)https://www.cnblogs.com/hixiao ...
- python读取json数据格式问题_浅谈Python中的异常和JSON读写数据的实现
异常可以防止出现一些不友好的信息返回给用户,有助于提升程序的可用性,在java中通过try ... catch ... finally来处理异常,在Python中通过try ... except .. ...
- python 忽略 异常_如何忽略Python中的异常?
python 忽略 异常 什么是例外? (What is an Exception?) An exception is an event, which occurs during the execut ...
- 【华为云技术分享】Python 中的异常和错误
[摘要] 异常就是程序运行时发生错误的信号,在python中,错误触发的异常如下 异常和错误 第一:程序中难免出现错误,而错误分成两种 1.语法错误(这种错误,根本过不了python解释器的语法检测, ...
- python中什么是异常_一文教你读懂 Python 中的异常信息
在写 Python 代码的时候,当代码中出现错误,会在输出的时候打印 Traceback 错误信息,很多初学者看到那一堆错误信息,往往都会处于懵逼状态,脑中总会冒出一句,这都是些啥玩意.如果你是第一 ...
- python中的异常分类_列举 5 个 Python 中的异常类型以及其含义【面试题详解】
今天爱分享给大家带来列举 5 个 Python 中的异常类型以及其含义[面试题详解],希望能够帮助到大家. BaseException +-- SystemExit +-- KeyboardInter ...
- python中formatter的用法_Python pyplot.FuncFormatter方法代码示例
本文整理汇总了Python中matplotlib.pyplot.FuncFormatter方法的典型用法代码示例.如果您正苦于以下问题:Python pyplot.FuncFormatter方法的具体 ...
最新文章
- 查看服务器硬盘负载——判断硬盘是否为瓶颈
- DHCP服务器的搭建
- element ui input视图没刷新_聊聊前端 UI 组件:组件体系
- nodejs 实践:express 最佳实践(五) connect解析
- CSAPP(8):系统级IO
- Ubuntu16.04安装CDH
- [转载]如何在只能力加载的有限元程序里面实现按位移加载
- CodeSmith实用技巧(八):生成的代码输出到文件中
- 嗓子痛引发大抢救!33岁程序员的垂死经历,为所有人敲响警钟!
- Markdown语法--整理
- 【干货】华为-智能世界2030:构建万物互联的智能世界
- 语音识别软件、语音识别平台和语音识别技术
- c语言构成循环结构的是,C语言循环结构选择题
- Chapter 5 Blood Type——15
- JqueryEasyUI $.Parser
- 小型微型计算机投稿流程,小型微型计算机系统
- 利用ptrace设计一个简单的debugger调试器
- 微信动态表情保存到手机相册
- 你想成为阿里巴巴的一名数据工程师吗?以下的应聘要求你得好好看了
- 贷款行业怎样运用运营商数据找精准客户?
热门文章
- 每次进入命令需要重新source的解决方法
- 时间在流逝——上还是不上大学?
- [需求管理-4]:需求分析全过程:需求分析+资源评估+项目计划
- Fully Attentional Network for Semantic Segmentation
- backpressure 背压介绍
- JEM software ticket45:Console output error of nQP when LCU level rate control is enabled
- AutoLisp从入门到放弃(十七)
- 解决ORA-28000:the account is locked,解锁oracle用户
- 范式存在定理及其证明
- Ubuntu18.04使用RPLIDAR A2M12雷达出错的解决办法