二十一、异常处理
注:语法报错无法抑制(无法抛出异常)
1、异常处理(30)
IndexError:索引超出序列的范围
KeyError:字典中查找一个不存在的关键字
NameError:尝试访问一个不存在的变量
IndentationError:缩进错误
AttributeError:尝试访问未知的对象属性s
Stoplteration:迭代器没有更多的值
AssertionError:断言语句(assert)失败 [测试领域]
assert断言,猜后面的表达式是否正确,如果猜对了,什么反应都没有,猜错了,直接报错
if和assert的区别:if判定时选择执行或不执行;assert判定时选择报错或不报错
EOFError:用户输入文件末尾标志EOF(Ctrl+d)
FloatingPointError:浮点计算错误
GeneratorExit:generator.close()方法被调用的时候
ImportError:导入模块失败的时候
KeyboardInterrupt:用户输入中断键(Ctrl+c)
MemoryError:内存溢出(可通过删除对象释放内存)
NotImplementedError:尚未实现的方法
OSError:操作系统产生的异常(例如打开一个不存在的文件)
OverflowError:数值运算超出最大限制
ReferenceError:弱引用(weak reference)试图访问一个已经被垃圾回收机制回收了的对象
RuntimeError:一般的运行时错误
SyntaxError:Python的语法错误
TabError:Tab和空格混合使用
SystemError:Python编译器系统错误
SystemExit:Python编译器进程被关闭
TypeError:不同类型间的无效操作
UnboundLocalError:访问一个未初始化的本地变量(NameError的子类)
UnicodeError:Unicode相关的错误(ValueError的子类)
UnicodeEncodeError:Unicode编码时的错误(UnicodeError的子类)
UnicodeDecodeError:Unicode解码时的错误(UnicodeError的子类)
UnicodeTranslateError:Unicode转换时的错误(UnicodeError的子类)
ValueError:传入无效的参数
ZeroDivisionError:除数为零
# IndexError
lst = [1, 2, 3]
print(lst[100])
# KeyError
dic = {"a": 1, "b": 2}
print(dic["c"])
# NameError
print(asd)
# IndentationError
if 5 == 5:
print(1)
print(2)
# AttributeError
class MyClass:
a = 100
obj = MyClass
obj.abc
# Stoplteration
it = iter(range(2))
ret = next(it)
ret = next(it)
ret = next(it)
# AssertionError
assert 3 < 4
assert 3 > 4
if 3 < 4 :
pass
2、异常处理的基本语法
(1)普通异常处理:
try … except …
把有问题的代码放在try这个代码块中,如果出现了异常,直接执行except代码块
作用:防止异常错误,终止程序
(2)带有分支的异常处理:
except + 异常错误类
特指在发生这类异常错误时,要执行的分支
(3)处理迭代器的异常错误
StopIteration是异常错误类
StopIteration as e 给 StopIteration这个类的对象起一个别名叫做e
(4)异常处理的其它方法
try … finally … 不论代码是否报错,都必须要执行的代码放到finally中,finally中的代码块在报错误后会继续执行
try … except … else … 如果try代码块没有报错,就执行else这个分支,如果有报错就不执行这个分支
(5)额外for/while … else 如果遇到break异常终止了循环,不会执行else这个代码块
# (1)
try:
lst = [1, 2, 3, 4]
print(lst[100])
except:
pass
# print("This is an error")
# (2)
try:
lst = [1, 2, 3, 4]
print(lst[100])
dic = {"a": 1, "b": 2}
dic['ccc']
print(ccc)
except IndexError:
print("索引超出范围了")
except KeyError:
print("字典的键不存在")
except:
print("有异常错误")
# (3)
def mygen():
yield 1
yield 2
return "pop 94 me"
gen = mygen()
try:
ret = next(gen)
ret = next(gen)
ret = next(gen)
except StopIteration as e:
print("迭代器取值错误,越界了")
print(e)
# (4)
# try ... finally ...
try:
lst = [1, 2, 3, 4]
print(lst[100])
finally:
print(2)
print(3)
print("end结束")
print(666)
print(888)
# try ... except ... else ...
try:
print(1)
lst = [1, 2, 3, 4]
# print(lst[100])
except:
pass
else:
print("正常执行结束")
# (5)
for i in range(10):
print(i)
if i == 5:
break
else:
print("循环结束")
3、主动异常抛出
(1)基本语法:
raise + 异常错误类 or 异常错误对象(默认不写raise接收的是BaseException)
BaseException 所有异常类的父类(基类,超类)(子类,衍生类)
Exception 常规异常类的父类
(2)自定义异常MyException:务必继承父类 BaseException
系统的底层获取行数和文件名的函数(只有在程序异常时才能触发)
# (1)
try:
raise BaseException
except BaseException:
pass
try:
raise
except:
print(11)
#(2)
#(了解)系统底层获取行数和文件名的函数( 只有在程序异常时才能触发 )
def return_errorinfo(n):
import sys
f = sys.exc_info()[2].tb_frame.f_back
if n == 1:
return str(f.f_lineno) # 返回当前行数
elif n == 2:
return f.f_code.co_filename # 返回文件名
# 只有在抛出错误的时候,里面的行号和文件名才能获取到
def get_value(n):
try:
raise
except:
return_errorinfo(n)
class MyException(BaseException):
def __init__(self, num, msg, line, file):
# 错误号
self.num = num
# 错误信息
self.msg = msg
# 错误行号
self.line = line
# 错误文件
self.file = file
sex = "雌雄同体"
try:
if sex == "雌雄同体":
raise MyException(404, "人类没有雌雄同体", get_value(1), get_value(2))
except MyException as e:
print(e.num)
print(e.msg)
print(e.line)
print(e.file)