异常处理
一、什么是异常处理
-
程序中的两种异常:
- 1、语法错误: 空格 缩进以及其他语法规则(一般在语法检测的时候就会报错)
- 2、逻辑错误:程序整体能编译,但是在运行时,因具体的逻辑出现问题,例如:input的内容转int
- 3、异常就是程序运行时发生错误的信号,在Python中,错误触发的异常如下:异常发生后后面的代码不执行。

-
在python中不同异常可以用不同的类型去标识(python将同一类型的错误类型进行统一),不同的类对象标识不同的异常。
x常见异常AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性xIOError 输入/输出异常;基本上是无法打开文件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……
xxxxxxxxxxtry:被检测的代码块except 异常类型:try中一旦检测到异常,就执行这个位置的逻辑#1try: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()#2s1 = 'hello'try:int(s1)# except IndexError as e: # 如果捕捉不到相应的异常则报错except ValueError as e:print (e) #invalid literal for int() with base 10: 'hello'
-
-
多分支:
xxxxxxxxxx# 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 contentexcept 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之前还是会执行finallyfinally:print('after func')return innerdef func():print('在 func中')func() #结果 before func 在 func中 after func -
主动抛异常
-
raise 异常名称('打印信息') 一般结合自定义异常类使用,下文讲
xxxxxxxxxxraise ValueError('类型错误') # ValueError: 类型错误class Empty(Exception):def __init__(self,msg):self.msg = msgsuper().__init__()def __str__(self):return self.msgraise Empty('我报错了!') #__main__.Empty: 我报错了!#2class Empty(Exception): #自定义类def __init__(self,msg):self.msg = msgsuper().__init__()def __str__(self):return self.msgclass 班级: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。
xxxxxxxxxx#1、assert 1 == 5,'1 不等于 5 在报错时打印这段话' #AssertionError: 1 不等于 5 在报错时打印这段话#2、unittest常用的断言方法:1.assertEqual(self, first, second, msg=None)--判断两个参数相等:first == second2.assertNotEqual(self, first, second, msg=None)--判断两个参数不相等:first != second3.assertIn(self, member, container, msg=None)--判断是字符串是否包含:member in container4.assertNotIn(self, member, container, msg=None)--判断是字符串是否不包含:member not in container5.assertTrue(self, expr, msg=None)--判断是否为真:expr is True6.assertFalse(self, expr, msg=None)--判断是否为假:expr is False7.assertIsNone(self, obj, msg=None)--判断是否为None:obj is None8.assertIsNotNone(self, obj, msg=None) -
自定义异常
xxxxxxxxxxclass EvaException(BaseException):def __init__(self,msg):self.msg=msgdef __str__(self):return self.msgtry:raise EvaException('类型错误')except EvaException as e:print(e) #类型错误


浙公网安备 33010602011771号