1.异常处理
- Bug:意思是’臭虫’或’虫子’,现在系统或程序中的缺陷或者错误
- 代码有语法问题,无法解释运行,必须改正后才能运行称为”错误“
- 代码没有语法问题,可以运行,但会出运行时的错误,例如除零错误,下标越界等问题,在运行期间检测到的错误被称为"异常"
- 出现异常必须处理否则程序会终止执行,用户体验很差,Python支持程序员自己处理就按测到的异常。
2.try-except语句
- Python中,提供try-except语句捕获异常处理,可能捕获异常放入try语句快中,把处理结果放在except语句快中,当try语句快中的代码出现错误,执行except语句快中代码,如果try语句快代码没问题,except语句快不会执行
- 使用try…except语句捕获异常时,如果在except后面不指定异常名称,表示捕获全部异常
语法:
try:
block1
except [ExceptionName [as alias] ]:
block2
#"as alias":当前异常指定一个别名,通过该别名,可以记录异常具体内容
# 不能把所有的代码都放到try中,降低系统效率,浪费资源
# 可以多个except模块,从上往下应该由子类到父类,由精确到模糊
# 从上往下匹配异常的类型,如果能匹配到则执行对应处理模块,然后跳到异常处理模块后继续执行程序
def division():
num1 = int(input("请输出被除数:")) # 用户输入提示,并记录
num2 = int(input("请输入除数:"))
result = num1/num2 # 执行出发运算
print(result)
if __name__ == '__main__':
try: # 捕获异常
division() # 调用除法的函数
except ZeroDivisionError: # 处理异常
print("输入错误:除数不能为0") # 输出错误原因
3.try-except-else语句
- Python中,有另外一种异常处理结构,try…except…else语句,指定当try语句块中没有发现异常时执行的语句块,如果发现执行except语句快
def division():
num1 = int(input("请输出被除数:")) # 用户输入提示,并记录
num2 = int(input("请输入除数:"))
result = num1/num2 # 执行出发运算
print(result)
if __name__ == '__main__':
try: # 捕获异常
division() # 调用除法的函数
except ZeroDivisionError: # 处理异常
print("\n输入错了:除数不能为0")
except ValueError as e: # 处理ValueError异常
print("输入错误:",e)
else:
print("程序执行完成......")
4.try-except-finally语句
- 完整的异常处理语句应该包含finally代码块,通常情况下,无论程序中有无异常产生,finally代码快中的代码都会被执行
- 使用except子句是为了允许处理异常,无论是否引发了异常,使用finally子句都可以执行。如果分配了有限的资源(如打开文件),则应释放这些资源的代码防止在finally语句块中
语法:
try:
block1
except [ ExceptionName [ as alias ] ]:
block2
finally:
block3
def division():
num1 = int(input("请输出被除数:")) # 用户输入提示,并记录
num2 = int(input("请输入除数:"))
result = num1/num2 # 执行出发运算
print(result)
if __name__ == '__main__':
try: # 捕获异常
division() # 调用除法的函数
except ZeroDivisionError: # 处理异常
print("\n输入错了:除数不能为0")
except ValueError as e: # 处理ValueError异常
print("输入错误:",e)
else:
print("程序执行完成......")
finally: # 无论是否抛出异常都执行
print("释放资源,并关闭")
5.黑洞异常
- 吞掉所有异常,不报错不提示
# 吞掉所有异常
try:
print(1 / 0)
except:
pass
6.raise语句抛出异常
- 某个函数或方法可能产生异常,不想在当前函数或方法处理这个异常,可以使用raise语句在函数或方法中抛出异常
- ExceptionName (reason) 参数中(reason)可以省略,如果省略,则在抛出异常时,不附带任何描述
语法:
raise [ExceptionName [(reason)]]
try:
print("问女神:这周六有空吗,一起看日出吧")
raise Exception("女神:周六和姐妹们逛商场")
except Exception as e:
print("屌丝:正好我也要买点东西,一起去")
try:
raise Exception("女神:太累了,咱们回去吧")
except:
print("屌丝:前面有家咖啡馆,一起喝杯咖啡休息一下")
'''
输出:
问女神:这周六有空吗,一起看日出吧
屌丝:正好我也要买点东西,一起去
屌丝:前面有家咖啡馆,一起喝杯咖啡休息一下
'''
7.assert断言
- 语法:assert条件【,异常描述字符串】
- 执行流程:如果条件为假,则抛出AssertionError,条件为真,就当assert不存在
- 作用:对于可能出现问题的代码,加上断言,方便问题排查
print('start')
num = int(input('请输入一个1`9的整数:'))
assert 0 < num <= 9,'num不在1~9'
print('end')
'''
输入:0
输出:AssertionError: num不在1~9
'''
8.自定义异常类
- 如果系统异常类型满足不了业务需求,那么可以自己定义异常类来处理。
- 自己定义的异常类必须继承BaseException或Exception
步骤:
1.在自定义异常的构造函数中,调用父类构造函数
2.重写__str__方法输出异常信息
3.编写异常处理方法处理异常
class CustomError(BaseException): # 继承BaseException
def __init__(self,msg):
super().__init__() # 调用父类初始化方法
self.msg = msg
# 重写__str__,输出异常信息
def __str__(self):
return self.msg
# 自定义异常处理方法
def handle_exception(self):
print('异常处理')
try:
raise CustomError('自定义异常')
except CustomError as e:
print(e)
e.handle_exception() # 异常处理
9.内件异常类的层次