一.认识异常处理
程序错误分为两种:语法错误 和 异常错误
语法错误:代码没有按照python规定语法去写,发明创造产生的错误
异常错误:在代码语法正确的前提下,程序报错就是异常
try...except... 基础语法 用于解决程序异常问题
raise 可以主动抛异常,异常类可以自定义
1.异常的分类
(1)IndexError 索引超出序列范围
# lst = [1,2,3,4]
# print(lst[100])
(2)KeyError 字典中查找一个不存在的关键字
# dic = {"a":1,"b":2}
# print(dic["c"])
(3)NameError 尝试访问一个不存在的变量
print(abc)
(4)IndentationError 缩进错误
# if 5 == 5 :
# print(1)
# print(2)
(5)AttributeError 尝试访问未知的对象属性
# class MyClass():
# a = 100
# obj = MyClass()
# obj.abc
(6)StopIteration 迭代器没有更多的值
# it = iter(range(3))
# res = next(it)
# res = next(it)
# res = next(it)
# res = next(it)
(7)AssertionError 断言语句(assert) 失败 用于测试领域
assert断言,就是猜,猜一猜后面的表达式是否正确
如果猜对了,什么反应也没有,如果猜错了,直接报错
if 判定时选择执行或者不执行, assert判定时选择报错或者不报错
assert 3<4
assert 3>4 # 报错
if 3<4 :
pass
2.异常处理的基本语法
(1)基本语法
try...except...
把有问题的代码放到try这个代码块中
如果出现了异常,直接执行except这个代码块
作用:防止异常错误终止程序
try:
lst = [1,2,3,4]
print(lst[100])
except:
pass
# print("这里有异常错误")
(2)带有分支条件的异常处理
except + 异常错误类 特指在发生这类异常错误时,要执行的分支
try:
# IndexError
# lst = [1,2,3,4]
# print(lst[100])
# KeyError
# dic = {"a":1,"b":2}
# dic["ccc"]
# NameError
print(abcdefg)
except IndexError:
print("索引超出了范围")
except KeyError:
print("字典的键不存在")
except:
print("有异常错误~")
(3)处理迭代器的异常错误
gen = mygen()
# 通过try except 接收生成器函数中的返回值
try:
res = next(gen)
res = next(gen)
res = next(gen)
except StopIteration as e:
"""
StopIteration是异常错误类
StopIteration as e 给StopIteration这个类的对象起一个别名叫做e
__str__ 当打印对象时,自动触发该魔术方法,自动接收return的返回值
"""
print("迭代器取值错误,越界了")
print(e)
(4) 异常处理的其他写法
1)try...finally... 不论代码是否报错,把必须要执行的代码放到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代码块没有报错,就执行else这个分支,如果有报错,就不执行else分支
try:
# print(1)
lst = [1,2,3,4]
print(lst[100])
except:
pass
else:
print("正常执行结束....")
3)for / while ...else 如果遇到break异常终止了循环,则不会执行else这个代码块
for i in range(10):
print(i)
if i == 5:
break
else:
print("循环结束")
3.主动抛异常(raise)
raise + 异常错误类 or 异常错误类对象
BaseException 是所有异常类的父类(基类,超类)
Exception 是常规异常类的父类
(1)基本语法
try:
# 主动抛出异常.
raise BaseException
except BaseException:
pass
# 简写 ( 默认接受的都是BaseException )
try:
raise
except:
print(11)
(2)自定义异常类 MyException(务必继承父类BaseException)
#(了解)系统底层获取行数和文件名的函数( 只有在程序异常时才能触发 )
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 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 + 异常错误类对象 => 主动抛异常
raise MyException(404,"人类没有雌雄同体",get_value(1),get_value(2))
# 给MyException的类对象起别名叫做e
except MyException as e:
# 对象.属性
print(e.num) # 404
print(e.msg) # 人类没有雌雄同体
print(e.line)# 59
print(e.file)# E:/python30/day26/3.py