为什么要用异常处理?
写代码出现报错的的情况,首先检查逻辑是不是有问题,在逻辑没问题还会报错的情况下,找到具体报错的那一行代码,在这行代码上加上try,再根据错误类型进行处理.
什么情况下需要进行异常处理?
在我们程序写定的时候无法预料的错误和异常,就需要在代码中处理
首先我们要杜绝一些常规的错误,但是是不可能滴...你总会错的
name # NameError class A:pass A= error # AttributeError 属性错误 # 所有的缩进错误,语法错误, 尽量在写代码的时候进行避免 这几种报错尽量少出现!
1.常见的异常类型
int('abc') ValueError iterator = iter([1,2]) #iter 迭代器 ,括号里面放可迭代的参数 for i in iterator: # 通过for循环 取值 print(i) #取得1,2 print(next(iterator)) #但是再通过next方法取值已经没了 就会出现 StopIteration 异常 iterator.__next__()
2.异常的结构和语法
单分支-1
try:
有可能出错的代码
except 错误类型1:
try: iterator = iter([]) iterator.__next__() except StopIteration: print('这样就不会报错了,还可以正常取到值')
单分支-2
try:
有可能出错的代码
except (错误类型1,错误类型2,...):
l = ['生活','压力','__eq__','责任'] try: meusr = int(input('请输出序号显示l内容: ')) print(l[meusr-1]) except (ValueError,IndexError): #同时处理掉值错误和超出l索引异常的情况 print('请输入1个数字')
多分支-1
try:
有可能出错的代码
except 错误类型1:
处理这个错误
except 错误类型2:
l = ['生活','压力','__eq__','责任'] try: meusr = int(input('请输出序号显示l内容: ')) #可以看出输入除了数字的值或超过l索引值就会报错 print(l[meusr-1]) except ValueError: #首先处理掉值错误的情况 print('请输入1个数字') except IndexError: #处理超出l范围的情况 print('输入的数字无效')
as语句的应用
使用 as 语句得到一个错误信息的变量,使用这个变量,就可以知道错误的具体信息,在一定程度上方便了我们代码测试
l = ['生活','压力','__eq__','责任'] try: meusr = int(input('请输出序号显示l内容: ')) print(l[meusr-1]) except (ValueError,IndexError) as err: #当然 as 得到这个变量可以为任意 print(type(err),err) meusr = 6 就会输出<class 'IndexError'> list index out of range meusr = a 就会输出<class 'ValueError'> invalid literal for int() with base 10: 'a'
万能异常(Exception)
和其他异常配合使用的时候,默认放在最后,尽量不要滥用万能异常
程序开发完后,在最外层添加异常处理,保证程序运行不会出现意外
try:
可能出错的代码
expect:Exception as e:
示例1
def func(): so def main(): func() try: main() except Exception as e: print('出错了..',e)
示例2
l = ['生活','压力','__eq__','责任'] try: meusr = int(input('请输出序号显示l内容: ')) print(l[meusr-1]) name except (ValueError,IndexError) as err: print(type(err),err) except Exception as err: print(type(err),err)
#程序首先走ValueError,IndexError 进行比对,有异常处理,并输出异常类型 如果没有走万能异常并输出异常类型
注意:所有的异常处理都应该用最基础的最贴近的异常类型去处理它,而不是滥用万能异常
else结构
try:
有可能出错的代码
except (错误类型1,错误类型2,...):
处理这个错误
else:
不发生异常要做的操作
try: name except Exception as e: print(e) #输出 name 'name' is not defined else: print('-------') #并没有执行打印
finally
无论如何都会执行,关闭文件归还系统资源(网上的连接数据库的连接,遇到return 遇到程序报错结束,都会执行finally,再return或者报错停止运行!
def func(): try: f = open('file','w') ret = f.read() #写的模式下无法读 return ret # f.close() #上面代码报错后直接执行except,所以写到 finally方法中 except Exception: print('报错了---') # 处理异常后执行 finally: # 无论有没有异常都会执行 f.close() #鉴于文件打开后并没有关闭,执行finally print('closed---') func()
raise抛出异常
普通示例1
try: f = open('file','r') ret = f.read() finally: f.close() print('closed---') raise ImportError
抽象类示例
在框架和规范中,提示按照规则写代码,加入主动抛出异常,提示规范编程
class A: def func(self): raise NotImplementedError # 抛出异常,就是提示对象b只找自己类中的func,不再走父类中的func class B(A): def func(self): print('B的func') b = B() b.func()
自定义异常,也就是自己写报错
class Nocoursre(BaseException): def __init__(self,msg): self.msg = msg def __str__(self): return self.msg err = Nocoursre('没有这个课程') print(err) raise Nocoursre('没有这个课程') class Nocourse(BaseException): def __str__(self): return '没有这个课程' raise Nocourse() #主动报异常 输出 __main__.NoCourse: 没有这个课程
断言
assert 必须满足的条件返回bool值, 否则返回False 报错,如果是True就执行
assert 1 == 1 #True就执行 print('继续执行')
...