概念
语法错误:代码将不被执行,代码分析器直接指出语法错误行
异常:代码没有出现错误,但是当程序运行起来之后,会在控制台上报错,这种错误称为异常
异常的特点:当程序在执行过程中遇到异常,而且异常没有被处理,则程序会终止在出现异常的地方,代码不会继续向下执行
解决问题:当程序遇到异常的时候,让程序越过异常继续向下执行
本质【工作机制】:只是将异常屏蔽掉,不影响其他代码的执行,并没有真正的处理,常见的处理方式:捕获和抛出
常见异常
AttributeError:指定对象没有指定的属性
StopIteration:迭代器没有更多的值进行遍历
ZeroDevisionError:不能除以或者取模0
KeyError:字典中没有指定的键
NameError:没有声明或者初始化变量【某个对象没有某个指定的属性】
UnboundLocalError:访问未初始化的本地变量
SyntaxError:Python语法错误
TypeError :对类型进行无效的操作
异常的处理方式(try-except-else,try-except-finally,raise:抛出一个异常,assert:断言/了解一个异常,异常嵌套,自定义异常)
try-except-else
说明:try对应的代码块被称为代码监测区域,用来监测其中的代码是否有异常【将可能存在异常的代码写在try代码块中】;如果try中的代码出现了异常,则try中的代码会终止在出现异常的代码处,则直接执行except代码块,具体执行哪个except代码块,取决于出现了什么样的异常,此处except块并不是真正处理异常,只是做了屏蔽【拦截】,可以让后面的代码正常执行;else可有可无,根据具体的需求而定
情况一:使用except带一个异常类型
#情况一:使用except带一个异常类型 try: #可能存在异常的代码 num = int(input("请输入一个数字:")) print(10 / num) pass except ValueError as e: #此处的e就相当于一个ValueError的对象,所有异常的类中将__str__重写过了,返回一个异常的描述字符串 print(e) print("hello")
情况二:使用多个except异常类型
#情况二:使用多个except异常类型 #工作原理;如果try中代码出现了异常,则在except分支中从上往下挨个进行匹配错误码,如果匹配上了,则整个try-except结束 try: #可能存在异常的代码 num = int(input("请输入一个数字:")) print(10 / num) pass except KeyError as e: print(e) except ValueError as e: print(e) except ZeroDivisionError as e: print(e) except UnboundLocalError as e: print(e)
情况三:except不带任何异常类型
#情况三:except不带任何异常类型 #工作原理:不管try中出现什么样的异常,都会执行except块 try: #可能存在异常的代码 num = int(input("请输入一个数字:")) print(10 / num) pass except: print("出现了异常")
情况四:一个except后面可以跟多种错误码
#情况四:一个except后面可以跟多种错误码 #工作原理;只要try中出现的异常匹配上元组中的任意一个错误码即可 try: print(10 / 0) pass except (ZeroDivisionError,KeyError,ValueError): print("出现了异常")
情况五:else分支,只有当try中的代码没有异常出现的时候,才会执行else分支
除了在try中直接检测可能存在异常的代码,也可以检测可能存在异常代码所在的函数
所有异常的父类是BaseException【Exception】,如果BaseException出现在except语句的第一个,则直接会被执行
try-except-finally:一般用来定义清理行为,表示代码执行完成之后都需要做的清理行为
说明:区别于else分支,不管try中代码有没有异常,finally块都会被执行
情况一:直接使用
#情况一:直接使用 try: print(10 / 0) except BaseException as e: print(e) finally: print("finally被执行了")
情况二:如果在try-except-finally语句中,在try或者except语句中出现return,finally仍然会被执行。使用场景:文件关闭,数据库关闭,为了避免资源的浪费
情况三:如果try中的异常没有匹配到相应的except语句,那么这个异常会在finally执行之后再次出现
#情况三:如果try中的异常没有匹配到相应的except语句,那么这个异常会在finally执行之后再次出现 try: print(10 / 0) except KeyError as e: print(e) finally: print("over")
raise:抛出一个异常。使用场景:自定义异常中
try: raise print(10 / 0) except ZeroDivisionError as e: print(e)
说明:raise表示实实在在的抛出了异常,为了不影响其他代码的执行,最终还是要通过try-except进行捕获
assert:断言/了解一个异常,预言成功,则获取结果,预言失败,则出现一个AssertionError异常,异常的信息描述是自定义的
def fun(num,divnum): #预言:预言成功,则获取结果,预言失败,则出现一个AssertionError异常,异常的信息描述是自定义的 assert (divnum != 0),"除数或者分母不能为0" return num / divnum print(fun(10,4)) print(fun(10,0))
异常嵌套
print("我想去拉萨") try: print("我准备乘飞机过去") raise Exception("由于天气大雾,飞机无法起飞") print("到拉萨了,拉萨真漂亮") except Exception as e: print(e) try: print("我准备乘火车过去") raise Exception("由于大暴雨,铁路断了") print("到拉萨了,拉萨真漂亮") except Exception as e: print(e) print("我骑自行车去") print("到拉萨了,拉萨真漂亮")
自定义异常
实现步骤:
a.自定义一个类,继承自Exception类或者BaseException
b.书写构造函数,设置一个参数,用于保存异常信息
c.重写__str__函数,返回异常信息
d.定义一个成员函数,用来处理异常class MyException(Exception): #书写构造函数,设置一个参数,用于保存异常信息 def __init__(self,msg): ##调用父类中的构造函数,目的是将系统的异常机制引用过来 super(MyException,self).__init__() self.msg = msg #重写__str__函数,返回异常信息 def __str__(self): return self.msg #定义一个成员函数,用来处理异常 def handle(self): print("处理异常") try: raise MyException("自己的异常类型") except MyException as e: print(e) e.handle()