文章目录
Python常见异常类型
所报错误 | 缘由 |
---|---|
zeroDivisionError | 除(或取模)零(所有数据类型) |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
NameError | 未声明初始化对象(没有属性) |
SyntaxError | python语法错误 |
ValueError | 传入无效参数 |
OSError | 操作系统异常(如:文件打开异常) |
keyboardInterrupt | 键盘中断错误(如:Ctrl+c使得程序异常退出) |
SystemExit | 由sys.exit()引发(唯一一个不被认为错误的异常) |
RuntimeError | (运行时错误)程序运行到一半,程序崩溃了 |
Base Exception(Exception) | 所有异常的父类 |
用try语句捕获异常
1. 完整语法结构
try:
可能触发异常的语句
except 错误类型1 [as 变量1]:
处理语句1
except 错误类型2 [as 变量2]:
处理语句2
except Exception [as 变量3]:
不是以上错误类型的处理语句(因为Exception 可接收所有异常)
else:
未发生异常执行的语句
finally:
无论是否发生异常都执行的语句
2. 注意事项
①:as 子句是用于绑定错误对象的变量,可以省略。
②:except子句可以有一个或多个,用来捕获某种类型的错误。多个except结构时,捕获异常顺序按照先子类后父类(从小到大)。为避免遗漏可能出现异常,建议在最后增加BaseException。
③:else子句最多只能有一个。
④:finally子句最多只能有一个。
3. 访问异常信息
如果程序需要在 except 块中访问异常对象的相关信息,则可通过为异常对象声明变量来实现。
所有的异常对象都包含了如下几个常用属性和方法:
\quad
args:该属性返回异常的错误编号和描述字符串。
\quad
errno:该属性返回异常的错误编号。
\quad
strerror:该属性返回异常的描述宇符串。
\quad
with_traceback():通过该方法可处理异常的传播轨迹信息。
try:
text = open("a.txt")
except Exception as e:
# 访问异常的错误编号和详细信息
print(e.args)
# 访问异常的错误编号
print(e.errno)
# 访问异常的详细信息
print(e.strerror)
raise抛出异常
1. 说明
当程序出现错误,python会自动引发异常,也可以通过raise显示地引发异常。一旦执行了raise语句,raise后面的语句将不能执行。
2. 作用
抛出一个错误,让程序进入异常状态。
3. 目的
在程序调用层数较深时,向主调函数传递错误信息要层层 return 比较麻烦,所以人为抛出异常,可以直接向外传递错误信息。
4. 使用语法
①:单独一个 raise
\quad\;\,\,
在使用 raise 语句时可以不带参数,此时 raise 语句将会自动引发当前上下文激活的异常;否则,通常默认引发 RuntimeError 异常。
\quad\;\,\,
作用:捕捉到了异常,但是又想重新引发它(传递异常),可以使用不带参数的raise语句。
raise
Traceback (most recent call last):
File "C:/Users/chenh/PycharmProjects/pythonProject/main.py", line 1, in <module>
raise
RuntimeError: No active exception to reraise
②:raise 异常类名称
\quad\;\,\,
raise 后带一个异常类名称,表示引发执行类型的异常。
raise ZeroDivisionError
Traceback (most recent call last):
File "C:/Users/chenh/PycharmProjects/pythonProject/main.py", line 1, in <module>
raise ZeroDivisionError
ZeroDivisionError
③:raise 异常类名称(描述信息)
\quad\;\,\,
在引发指定类型的异常的同时,附带异常的描述信息。
raise ZeroDivisionError("除数不能为零")
Traceback (most recent call last):
File "C:/Users/chenh/PycharmProjects/pythonProject/main.py", line 1, in <module>
raise ZeroDivisionError("除数不能为零")
ZeroDivisionError: 除数不能为零
5. 应用举例
一. 我们手动让程序引发异常,很多时候并不是为了让其崩溃。事实上,raise 语句引发的异常通常用 try except(else finally)异常处理结构来捕获并进行处理。
try:
num = input("输入一个数:")
# 判断用户输入的是否为数字
if not num.isdigit():
raise ValueError("输入必须是数字")
except ValueError as e:
print("引发异常:", repr(e))
输入一个数:three
引发异常: ValueError('输入必须是数字')
在该例程中,当输入的不是数字时,程序会进入 if 结构,并执行 raise 引发ValueError 异常。虽然在程序中使用 raise 语句引发了异常,但是由于位于 try 块中,抛出异常会被 try 捕获,并由 except 块进行处理。因此程序可以正常执行,并不会导致程序崩溃。
Python repr()函数
二. 在使用 raise 语句时可以不带参数
try:
num = input("输入一个数:")
# 判断用户输入的是否为数字
if not num.isdigit():
raise ValueError("输入必须是数字")
except ValueError as e:
print("引发异常:", repr(e))
raise
输入一个数:three
引发异常: ValueError('输入必须是数字')
Traceback (most recent call last):
File "C:/Users/chenh/PycharmProjects/pythonProject/main.py", line 5, in <module>
raise ValueError("输入必须是数字")
ValueError: 输入必须是数字
重点关注位于 except 块中的 raise,由于在其之前我们已经手动引发了 ValueError 异常,因此这里当再使用 raise 语句时,它会再次引发一次。
自定义异常类型
1. 说明
Python中可以自定义自己的特殊类型异常,只需要从 Exception 基类或 Exception 的子类继承即可(直接或间接)。
2. 完整语法结构
class 类名Error(Exception):
def __init__(self,参数):
super().__init__(参数)
self.数据 = 参数
3. 应用举例
一. 在自定义异常类时基本不需要书写更多的代码,只要指定自定义异常类的父类即可。
class AgeError(ValueError):
pass
age = int(input('age: '))
if 0 <= age <= 200:
print(age)
else:
raise AgeError('age is not correct')
age: 500
Traceback (most recent call last):
File "C:/Users/chenh/PycharmProjects/pythonProject/main.py", line 9, in <module>
raise AgeError('age is not correct')
__main__.AgeError: age is not correct
二. 封装自定义错误信息
"""
年龄异常(0-200)
"""
class AgeError(Exception):
# 封装错误信息
def __init__(self, msg, age_value):
super().__init__(msg)
self.msg = msg
self.age_value = age_value
class People:
def __init__(self, age):
self.age = age
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
if 0 <= value <= 200:
self.__age = value
else:
raise AgeError("不符合", value)
try:
p1 = People(250)
print(p1.age)
except AgeError as e:
print("错误信息:", e.msg)
print("输入的年龄是:", e.age_value)
错误信息: 不符合
输入的年龄是: 250
python super()函数
python @property的介绍与使用
python @methodname.setter(文中第四点)
python中,单下划线属性类似于C++中的protected,双下划线类似于C++中的private,但是python中的私有属性仍可以通过_ClassName__FileName这种名字访问到,所以python没有真正意义上的私有。
python异常使用规范
- 不要过度使用异常
- 把异常和普通错误混淆在一起,不再编写任何错误处理代码,而是以引发异常来代替错误处理。
- 使用异常处理来代替流程控制。
- 不要使用过于庞大的 try 块
- 在 try 块里放置大量的代码,然后紧跟大量的 except 块,增加了编程复杂度。
- 不要忽略捕获到的异常
- 处理异常。对异常进行合适的修复,然后绕过异常发生的地方继续运行;或者用别的数据进行计算,以代替期望的方法返回值;或者提示用户重新操作……总之,程序应该尽量修复异常,使程序能恢复运行。
- 重新引发新异常。把在当前运行环境下能做的事情尽量做完,然后进行异常转译,把异常包装成当前层的异常,重新传给上层调用者。
- 在合适的层处理异常。如果当前层不清楚如何处理异常,就不要在当前层使用 except 语句来捕获该异常,让上层调用者来负责处理该异常。