异常处理
一、异常:程序运行时的错误
二、程序中的异常处理机制:
①程序中的所有异常都会被处理
②程序中的所有异常都需要手动处理
③如果没有手动处理异常,异常会交给Python解释器处理
处理的方式就是打印异常信息,并停止接收器
三、异常信息的三部分:
①异常的追踪信息:提示错误位置
②异常的类型:告知处理异常应该捕获什么类型
③异常的内容:告知错误信息
四、处理异常的语法:
try: # 会出现异常的代码块 except 异常类型 as 异常别名: # 异常处理逻辑 else: # 没有出现异常会执行该分支 finally: # 无论是否出现异常都会执行该分支 例如 try: print(adsdasadsdasadsdas) except NameError as e: print('异常信息:', e) else: print('被检测的代码块正常') finally: print('异常是否出现都会执行该分支') print('end') # 结果为 异常信息: name 'adsdasadsdasadsdas' is not defined 异常是否出现都会执行该分支 end
五、异常捕获的语法
将可能出现异常的代码放在try分支进行检测
如果不出现异常,正常执行内部所有代码
如果出现异常会进入except分支
# part1 # 1.建议大家对异常处理时,一次只处理一个异常 try: print(asdsdsdsdsdsdsdsdsdsdsdsdsd) # NameError except NameError: # except 后跟异常类型,如果不需要查看异常信息,可以省略异常信息 print('出现了NameError异常') try: ls = [1, 2, 3, 4, 5] print(ls[10]) # IndexError except IndexError as e: # 如果想知道异常信息,用别名接收 print('出现了IndexError异常: %s' % e) # 结果为 出现了NameError异常 出现了IndexError异常: list index out of range # part2 # 2.如果无法避免一句话或是一个完整的代码结构会出现多个可能的异常,需要在一个try中提供多个except # ls = [1, 2, 3, 4, 5] ls = (1, 2, 3, 4, 5, 6) # try: # print(ls[5]) # IndexError # ls.append(10) # AttributeError # except IndexError as e: # print('出现了IndexError异常: %s' % e) # except AttributeError as e: # print('出现了AttributeError异常: %s' % e) try: print(ls[5]) # IndexError ls.append(10) # AttributeError except (AttributeError, IndexError) as e: print('出现了异常: %s' % e) # 结果为: 6 出现了异常: 'tuple' object has no attribute 'append' # part3 # 3.有些异常提前无法明确,或是压根没有明确的必要,可以捕获异常的父类异常 ls = [1, 2, 3, 4, 5] # ls = (1, 2, 3, 4, 5, 6) try: print(ls[5]) # IndexError ls.append(10) # AttributeError except Exception as e: # 可以通过多态的应用,捕获父类,只要抛出的是该父类的子类异常,均可以被捕获 print('出现了异常: %s' % e) # BaseException:所有异常的基类 | Exception:常规错误的基类 # 结果为:出现了异常: list index out of range # part4 # 4.了了解 - try语法的else分支:当try检测的代码块没有出现异常,才会走else分支 try: print(aaaa) except Exception as e: print('出现了异常', e) else: print('没有异常') # 结果为:出现了异常 name 'aaaa' is not defined # part5 # 5.finally:无论是否出现异常都会执行该分支 try: f = open('1.txt', 'w', encoding='utf-8') f.write(b'123') except Exception as e: print('出现了异常', e) finally: print('无论是否出现异常都会执行该分支') f.close() # 文件只要打开,不管操作是否出现异常,都需要释放文件资源 print('end') # 结果为 出现了异常 write() argument must be str, not bytes 无论是否出现异常都会执行该分支 end
六、主动抛出异常
# raise ValueError('输入的不能被转换为int类型') def get_int(): num = input('num: ') try: return int(num) except ValueError: raise ValueError('输入的不能被转换为int类型') num = get_int() print(num)
七、自定义异常
①自定义异常的目的:想抛一个有意义的异常,但这个异常系统没有提供,自定义一个
②用法:
class PeopleNameError(Exception): # pass # 可以通过__init__明确外界的错误信息接收给那个属性 # 再在__str__中格式化外界捕获异常,打印异常信息的格式 def __init__(self, msg): self.msg = msg def __str__(self): return 'PeopleNameError: ' + self.msg def get_name(): name = input('name: ') if 'sb' in name.lower(): raise PeopleNameError('人名不能有敏感词汇') return name try: print(get_name()) except PeopleNameError as e: print(e) # PeopleNameError: 人名不能有敏感词汇
八、断言:只有满足断言条件,程序才能往下执行,反之抛出异常
num = int(input('num: ')) assert num < 0 # 断言:只有满足断言条件,程序才能往下执行,反之抛出异常 print(abs(num))