# 异常处理
# 什么是异常处理
程序中的两种异常:
- 1、语法错误: 空格 缩进以及其他语法规则(一般在语法检测的时候就会报错)
- 2、逻辑错误:程序整体能编译,但是在运行时,因具体的逻辑出现问题,例如:input的内容转int
- 3、异常就是程序运行时发生错误的信号,在Python中,错误触发的异常如下:异常发生后后面的代码不执行。
在python中不同异常可以用不同的类型去标识(python将同一类型的错误类型进行统一),不同的类对象标识不同的异常。
常见异常 AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x IOError 输入/输出异常;基本上是无法打开文件 ImportError 无法引入模块或包;基本上是路径问题或名称错误 IndentationError 语法错误(的子类) ;代码没有正确对齐 IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5] KeyError 试图访问字典里不存在的键 KeyboardInterrupt Ctrl+C被按下 NameError 使用一个还未被赋予对象的变量 SyntaxError Python 代码非法,代码不能编译(个人认为这是语法错误,写错了) TypeError 传入对象类型与要求的不符合 UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量, 导致你以为正在访问它 ValueError 传入一个调用者不期望的值,即使值的类型是正确的
Python中常见的异常类:
- BaseException # 所以异常的基类
- SystemExit # 解释器请求退出
- KeyboardInterrupt # 用户中断执行(^C)
- Exception # 常规错误的基类
Stoplteration # 迭代器没有更多值……
异常处理:通过捕捉异常,使程序进入另一个处理分支,执行特定的逻辑,使程序不崩溃
异常处理的目的:提高用户体验,提高代码的容错性
为什么要进行异常处理:检测到了一个错误时,触发异常,异常触发后且没被处理的情况下,程序就在当前异常处终止,后面的代码不会运行,谁会去用一个运行着突然就崩溃的软件。
# 如何进行异常处理
1、if判断式: 最常见的if语句只是针对一行代码,如果有多行需要使用多个if判断式
2、python为每一种异常定制了一个类型,提供特定的语法结构:
1、try …… except……
try: 被检测的代码块 except 异常类型: try中一旦检测到异常,就执行这个位置的逻辑 #实例一: try: f = open('a.txt') g = (line.strip() for line in f) print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g)) except StopIteration: f.close() -------------------------------------------------------- #实例二: s1 = 'hello' try: int(s1) # except IndexError as e: # 如果捕捉不到相应的异常则报错 except ValueError as e: print (e) #invalid literal for int() with base 10: 'hello'
多分支:
# try……except……except…… s1 = 'hello' try: int(s1) except IndexError as e: print(e) except KeyError as e: print(e) except ValueError as e: print(e) #万能异常 Exception,他可以捕获任意异常 s1 = 'hello' try: int(s1) except Exception as e: #e是异常的报错信息 print(e) #如果你统一用Exception,没错,是可以捕捉所有异常,但意味着你在处理所有异常时都使用同一个逻辑去处理(这里说的逻辑即当前expect下面跟的代码块,如果你想要的效果是,对于不同的异常我们需要定制不同的处理逻辑,那就需要用到多分支了 #try……except……else…… try: choose = int(input('请输入您想选择的商品序号 :')) print(l[choose-1]) except (ValueError,IndexError) as e1: #这里括号里可以写一类操作后出现的报错,以便做同样的处理逻辑 print(e1) print('请输入一个正常的序号') except Exception as e2: #如果上面异常被捕获就跳过 print(e2) else: print('执行我啦') # else: 如果try中的代码顺利的执行完,没有报错,那么就执行else中的代码是用来汇报整个try中的代码执行成功用的 # 一般情况下 else中的内容都是安全的不会有报错隐患,用于打印,区分在报错代码下一行执行 #try……except……except……finally…… try……finally…… def func(filename): try: f = open(filename,'r') content = f.read() return content except Exception as e: print(e) finally: # 无论如何都要执行 用于一些必要的收尾工作 f.close() print('一定会执行') ret = func('test') print(ret) #一定会执行 wjhal # finally : 必须执行 # 遇到return也先执行finally中的代码 *** # 遇到报错也在程序结束之前先执行finally中的代码 *** #列题 def wrapper(func): def inner(*args,**kwargs): try: print('before func') return func(*args,**kwargs) # 在return之前还是会执行finally finally: print('after func') return inner @wrapper def func(): print('在 func中') func() #结果 before func 在 func中 after func
主动抛异常
raise 异常名称('打印信息') 一般结合自定义异常类使用,下文讲
raise ValueError('类型错误') # ValueError: 类型错误 class Empty(Exception): def __init__(self,msg): self.msg = msg super().__init__() def __str__(self): return self.msg raise Empty('我报错了!') #__main__.Empty: 我报错了! ----------------------------------------------------------- #2、自定义异常类 class Empty(Exception): #自定义类 def __init__(self,msg): self.msg = msg super().__init__() def __str__(self): return self.msg class 班级: def __init__(self): self.students = ['赵大宝'] def get(self): if not self.students: raise Empty('学生列表已为空') else: return self.students.pop() clas = 班级() stu1 = clas.get() print(stu1) #赵大宝 stu2 = clas.get() print(stu2) #__main__.Empty: 学生列表已为空
断言:Python的断言就是检测一个条件,如果条件为真,它什么都不做;反之它触发一个带可选错误信息的AssertionError。
#1、 assert 1 == 5,'1 不等于 5 在报错时打印这段话' #AssertionError: 1 不等于 5 在报错时打印这段话 #2、unittest常用的断言方法: 1.assertEqual(self, first, second, msg=None) --判断两个参数相等:first == second 2.assertNotEqual(self, first, second, msg=None) --判断两个参数不相等:first != second 3.assertIn(self, member, container, msg=None) --判断是字符串是否包含:member in container 4.assertNotIn(self, member, container, msg=None) --判断是字符串是否不包含:member not in container 5.assertTrue(self, expr, msg=None) --判断是否为真:expr is True 6.assertFalse(self, expr, msg=None) --判断是否为假:expr is False 7.assertIsNone(self, obj, msg=None) --判断是否为None:obj is None 8.assertIsNotNone(self, obj, msg=None)
自定义异常
class EvaException(BaseException): def __init__(self,msg): self.msg=msg def __str__(self): return self.msg try: raise EvaException('类型错误') except EvaException as e: print(e) #类型错误