和Java类似程序运行有异常的时候,服务器会采用系统默认的异常处理机制:返回信息,终止程序。
异常的类型:
常见异常类型:
1.NameError:访问了未定义的变量
2.IndexError:越界访问
3.AttributeError:访问对象不存在的属性引发的异常
4.FileNotFoundError:未找到指定文件或目录引发的异常
9.1异常捕获语句:
9.1.1 使用try-except 语句捕获异常
格式:
try:
可能出错的代码
except [异常类型 [as error]]: #将捕获到的异常对象赋值给errror
捕获异常后的处理代码
except中可以指定异常类型,如果指定了异常类型,该字句就只对与指定异常类型相匹配的异常进行处理。否则处理try语句捕获的所有异常。except子句中的as关键字用于将捕获到的异常对象赋给error;
except子句后的代码是处理异常时执行的代码。
try-except 语句的执行过程为:优先执行try子句中可能执行的代码。若try子句中没有出现异常,忽略except子句继续向下执行。如果try出现异常,忽略try剩余代码,转而执行except子句。若程序出现的异常类型与except子句中指定的异常类型匹配,使用error记录信息,执行except子句中的代码,否则按系统默认的方式终止程序。
- 捕获单个异常
#捕获单个异常
num_one=int(input("请输入被除数:"))
num_tow=int(input("请输入除数:"))
try:
print("结果为:",num_one/num_tow)
except ZeroDivisionError:
print("出错了")
#捕获单个异常
num_one=int(input("请输入被除数:"))
num_tow=int(input("请输入除数:"))
try:
print("结果为:",num_one/num_tow)
except ZeroDivisionError as error:
print("出错了,原因:",error)
2.捕获多个异常
#捕获多个异常
try:
num_one=int(input("请输入被除数:"))
num_tow=int(input("请输入除数:"))
print("结果为:",num_one/num_tow)
except (ZeroDivisionError,ValueError) as error:
print("出错了,原因:",error)
3.捕获全部异常
捕获全部异常可以将except后的异常类型设置成Exception或省略不写
书上说,如果省略异常类型,except子句中无法获取异常的具体信息。
不知道为啥我省略后报错了。
#捕获所有异常
try:
num_one=int(input("请输入被除数:"))
num_tow=int(input("请输入除数:"))
print("结果为:",num_one/num_tow)
except Exception as error:
print("出错了,原因:",error)
9.1.2异常结构中的else子句
else子句可以与try-except语句组合成try-except-else结构。
若try监控的代码没有异常,程序会执行else子句。
try:
可能出错的代码
except [异常类型 [as error]]:
捕获异常后的处理代码
else:
没有异常的处理代码
9.1.3 异常结构中的finally子句
格式:
try:
可能出错的代码
except [异常类型 [as error]]:
捕获异常后的处理代码
else:
一定执行的代码
9.2抛出异常
9.2.1使用raise语句抛出异常
和Java一样,异常不仅可以由程序自动引发,还可以由程序员自己添加。
用raise语句和assert语句主动抛出。
格式:
raise 异常类 #格式1:使用异常类名引发指定的异常
raise 异常类对象 #格式2: 使用异常类的对象引发指定的异常
raise #格式3: 使用刚刚出现过的异常重新引发异常
1.使用异常类引发异常
使用raise异常类语句可以引发该语句中异常类对应的异常。
raise IndexError
2.使用异常类对象引发异常
raise IndexError()
可以通过字符串指定异常的具体信息
raise IndexError("所引下标越界")
3.重新引发异常
使用不带任何参数的raise可以引发刚刚发生的异常
try:
raise IndexError('索引下标超出范围')
except:
raise
首先发生异常,然后运行except
运行的时候又发生异常,然后终止程序。
9.2.2使用assert语句抛出异常
assert 表达式[,异常信息]
表达式的值为false(假)时触发异常。
num_one=int(input("请输入被除数"))
num_two=int(input("请输入除数"))
assert num_two !=0 ,'除数不能为0'
result=num_one/num_two
print(num_one,'/',num_two,'=',result)
9.2.3异常的传递
如果异常没有被处理,默认情况下将该异常传递到上一级,如果上一级仍然没有解决,继续向上传递。
直到异常被处理或程序崩溃。
#异常的传递。
def get_width():
print("get_width开始执行")
num=int(input("请输入除数:"))
width_len=10/num
print("get_width执行结束")
return width_len
def calc_area():
print("calc_area开始执行")
width_len=get_width()
print("calc_area执行结束")
return width_len*width_len
def show_area():
try:
print("show_area开始执行")
area_val=calc_area()
print(f"正方形的面积是:{area_val}")
print("show_area执行结束")
except ZeroDivisionError as e:
print(f"捕捉到异常:{e}")
show_area()
从22行开始执行,首先调用show_area(),show_area中调用了calc_area(),calc_area()又调用了get_with(),异常发生在get_with(),但是get_with没有设置异常捕获,所以异常会传递到,calc_area(),然后再传递,到show_area()。最后被捕获。
#异常的传递。
def get_width():
print("get_width开始执行")
num=int(input("请输入除数:"))
width_len=10/num
print("get_width执行结束")
return width_len
def calc_area():
print("calc_area开始执行")
width_len=get_width()
print("calc_area执行结束")
return width_len*width_len
def show_area():
print("show_area开始执行")
area_val=calc_area()
print(f"正方形的面积是:{area_val}")
print("show_area执行结束")
show_area()
9.3自定义异常
创建一个继承Exception类或Exception子类的类。(类名一般以Error结尾)。
class ShortInputError(Exception):
'''自定义异常类'''
def __init__(self, length,atleast) -> None:
self.length=length
self.atleast=atleast
try:
text=input("请输入密码:")
if len(text)<3:
raise ShortInputError(len(text),3)
except ShortInputError as result:
print("ShortInputError:输入的长度是%d,长度至少应该是%d"%
(result.length,result.atleast))
else:
print("密码设置成功")