异常处理
一、什么是异常处理
-
程序中的两种异常:
- 1、语法错误: 空格 缩进以及其他语法规则(一般在语法检测的时候就会报错)
- 2、逻辑错误:程序整体能编译,但是在运行时,因具体的逻辑出现问题,例如:input的内容转int
- 3、异常就是程序运行时发生错误的信号,在Python中,错误触发的异常如下:异常发生后后面的代码不执行。
-
在python中不同异常可以用不同的类型去标识(python将同一类型的错误类型进行统一),不同的类对象标识不同的异常。
x常见异常
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……
xxxxxxxxxx
try:
被检测的代码块
except 异常类型:
try中一旦检测到异常,就执行这个位置的逻辑
#1
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()
#2
s1 = '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 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
def func():
print('在 func中')
func() #结果 before func 在 func中 after func
-
主动抛异常
-
raise 异常名称('打印信息') 一般结合自定义异常类使用,下文讲
xxxxxxxxxx
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。
xxxxxxxxxx
#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)
-
自定义异常
xxxxxxxxxx
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) #类型错误