【愚公系列】2021年12月 Python教学课程 18-异常处理
前言
在程序运行过程中,总会遇到各种各样的问题和错误。有些错误是我们编写代码时自己造成的,比如语法错误、调用错误,甚至逻辑错误。还有一些错误,则是不可预料的错误,但是完全有可能发生的,比如文件不存在、磁盘空间不足、网络堵塞、系统错误等等。这些导致程序在运行过程中出现异常中断和退出的错误,我们统称为异常。大多数的异常都不会被程序处理,而是以错误信息的形式展现出来。
异常有很多种类型,Python 内置了几十种常见的异常,无需特别导入,直接就可使用。需要注意的是,所有的异常都是异常类,首字母是大写的!
在发生异常的时候,Python 会打印出异常信息,信息的前面部分显示了异常发生的上下文环境,并以调用栈的形式显示具体信息。异常类型作为信息的一部分也会被打印出来,例如 ZeroDivisionError,NameError 和 TypeError。
>>> 10 * (1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: Can't convert 'int' object to str implicitly
为了保证程序的正常运行,提高程序健壮性和可用性。我们应当尽量考虑全面,将可能出现的异常进行处理,而不是留在那里,任由其发生。
Python 内置了一套 try…except…finally(else)…的异常处理机制,来帮助我们进行异常处理。
提示:以下是本篇文章正文内容,下面案例可供参考
一、 异常的常见用法
1. try…except… 捕获单个异常
try:
print('---------test-start-------------')
open('123.txt',r)
print('---------test-end-------------')
except IOError:
pass
说明:
- 可能产生错误的代码放在 try 中
- 产生错误后要做的处理放到 except 中
2. 捕获多个异常
说明:
- 多个异常之间用逗号隔开
3. 获取异常的信息描述
使用关键字 as
4. 捕获所有异常
5. else 从句
说明:
- 如果没有捕获到异常,则运行 else 从句中的代码
6. try…finally…
在程序中,如果一段代码无论是否产生异常都必须要执行,那么这时就需要使用finally。比如关闭文件,释放锁,关闭数据库连接等。
try:
1/0
except:
pass
else:
print("else")
finally:
print("finally")
二、 异常的传递
python 中的异常具有嵌套处理机制。
- 如果 try 嵌套,那么如果里面的 try 没有捕获到这个异常,那么外面的 try 会接收到这个异常,然后进行处理。如果外面的 try 依然没有捕获到,那么再往外传递,直到程序最顶端如果还没有被捕获,那么将弹出异常。
- 如果异常发生在函数嵌套的情况,例如函数 F1— 》函数 F2 ---- 》函数 F3,当 F3中产生异常,但 F3 中并没有捕获这个异常时,那么这个异常会传递到函数 F2 中,如果 F2 中有异常处理则按照函数 F2 的处理方式执行;如果函数 F2 中也没有异常处理,那么这个异常会继续传递到函数 F1 中,操作同 F2 中。如果所有的函数都没有处理,那么就会进行默认的异常处理,即报错,打印出错信息。
三、 抛出异常
很多时候,我们需要主动抛出一个异常。Python 内置了一个关键字 raise,可以主动触发异常。raise 唯一的一个参数指定了要被抛出的异常的实例,如果什么参数都不给,那么会默认抛出当前异常。
四、 自定义异常
Python 内置了很多的异常类,并且这些类都是从 BaseException 类派生的。
下面是一些常见异常类,请把它们记下来!这样你在见到大多数异常的时候都能快速准确的判断异常类型。
异常名 | 解释 |
---|---|
AttributeError | 试图访问一个对象没有的属性 |
IOError | 输入/输出异常 |
ImportError | 无法引入模块或包;多是路径问题或名称错误 |
IndentationError | 缩进错误 |
IndexError | 下标索引错误 |
KeyError | 试图访问不存在的键 |
KeyboardInterrupt | Ctrl+C 被按下,键盘终止输入 |
NameError | 使用未定义的变量 |
SyntaxError | 语法错误 |
TypeError | 传入对象的类型与要求的不符合 |
UnboundLocalError | 试图访问一个还未被设置的局部变量 |
ValueError | 传入一个调用者不期望的值,即使值的类型是正确的 |
OSError | 操作系统执行错误 |
大多数情况下,上面的内置异常已经够用了,但是有时候你还是需要自定义一些异常。自定义异常应该继承 Exception 类,直接继承或者间接继承都可以,例如:
class MyExcept(Exception):
def __init__(self, msg):
self.message = msg
def __str__(self):
return self.message
try:
raise MyExcept('我的异常!')
except MyExcept as ex:
print(ex)
异常的名字都以 Error 结尾,我们在为自定义异常命名的时候也需要遵守这一规范,就跟标准的异常命名一样。
- 点赞
- 收藏
- 关注作者
评论(0)