错误与异常
什么是错误
• 语法错误(大小写拼写错误、括号不匹配等…)=> 不能正常执行
• 逻辑错误(程序运行正常,只是最后结果不符合预期)
什么是异常
• 程序运行过程中,出现的意料之外的错误
• 如:打开的文件不存在、被除数为0、操作的数据类型不对、存储错误,互联网请求错误…
回溯信息
• 当程序运行时,发生了未处理的异常,Python就将终止执行程序,并以堆栈回溯(Traceback,也 称向后追踪)的形式显示异常发生的上下文。
• 回溯信息告诉我们应该去哪里寻找问题的根源,对解决问题非常有帮助。
常见异常类型
int ('a')
# ValueError: invalid literal for int() with base 10: 'a'
print(b)
# NameError: name 'b' is not defined
print(1
# SyntaxError: unexpected EOF while parsing
print(1)
# IndentationError: unexpected indent
异常处理
1:即使程序出错,也不想让程序终止
2:如果出错了,需要特殊处理
try … except…
简单异常处理的格式:
执行顺序:
正常执行:try -> 执行代码 -> 结束
遇到异常:try -> 遇到异常 -> 调到except -> 结束
# 捕获所有异常
try:
a = input("请输入一个整数:")
print("您输入的数据是:", int(a))
print("try end!!")
# 捕获所有异常
except:
print("您输入的数据不合法,请重试")
print("end!")
# 请输入一个整数:a
# 您输入的数据不合法,请重试
# end!
except捕获错误与触发的错误不一致,程序就捕获不到,然后抛出异常
# 捕获指定异常(ValueError)
try:
a = input("请输入一个整数:")
print("您输入的数据是:", int(a))
print("try end!!")
# except ValueError as ex1:
except KeyError as ex1:
print("您输入的数据不合法,请重试")
print(ex1, type(ex1))
# 如果在程序处理过程中没有捕获到出现的错误,还是会抛出异常
# ValueError: invalid literal for int() with base 10: 'abc'
print("end!")
except可以有多个
except匹配到第一个就退出,不会执行异常处理后面的语句
如果父类异常捕获放在最前面,就会吞噬后面所有的子类异常
# 多个except分支
try:
a = input("请输入一个整数:")
print("您输入的数据是:", int(a))
mylist = []
print(mylist[10])
print("try end!!")
except Exception as ex0:
print("出错啦!")
except ValueError as ex1:
print("您输入的数据不合法,请重试")
print(ex1, type(ex1))
print("end!")
# 请输入一个整数:jl
# 出错啦!
# end!
try:
a = input("请输入一个整数:")
print("您输入的数据是:", int(a))
mylist = []
print(mylist[10])
print("try end!!")
# 子类在前
except ValueError as ex1:
print("您输入的数据不合法,请重试")
print(ex1, type(ex1))
# 父类在后
except Exception as ex0:
print("出错啦!")
print("end!")
# 请输入一个整数:kj
# 您输入的数据不合法,请重试
# invalid literal for int() with base 10: 'kj' <class 'ValueError'>
# end!
else结构 finally结构
else:没有发生异常时执行
try:
a = input("请输入一个整数:")
print("您输入的数据是:", int(a))
print("try end!!")
# 子类在前
except ValueError as ex1:
print("您输入的数据不合法,请重试")
print(ex1, type(ex1))
# 父类在后
except Exception as ex0:
print("出错啦!")
else:
print("没有错误")
print("end!")
# 请输入一个整数:6
# 您输入的数据是: 6
# try end!!
# 没有错误
# end!
不管try部分是否正常,不管异常有没有被捕获 , finally都正常执行
try:
a = input("请输入一个整数:")
print("您输入的数据是:", int(a))
print("try end!!")
# 子类在前
except ValueError as ex1:
print("您输入的数据不合法,请重试")
print(ex1, type(ex1))
# 父类在后
except Exception as ex0:
print("出错啦!")
else:
print("没有错误")
finally:
print("这里一直执行")
print("end!")
# 捕获到异常时:
# 请输入一个整数:a
# 您输入的数据不合法,请重试
# invalid literal for int() with base 10: 'a' <class 'ValueError'>
# 这里一直执行
# end!
# 没有异常时:
# 请输入一个整数:3
# 您输入的数据是: 3
# try end!!
# 没有错误
# 这里一直执行
# end!
try:
print("else test ....")
# 1/0
except ValueError:
print("error")
else:
print("else test end ...")
finally:
print("i am finally")
# else test ....
# else test end ...
# i am finally
# 没有捕获到出现的异常时:
try:
print("else test ....")
1/0
except ValueError:
print("error")
else:
print("else test end ...")
finally:
print("i am finally")
# else test ....
# i am finally
# Traceback (most recent call last):
# File "E:/scpythonProject/2022_4_30_模块与包/异常处理/异常处理.py", line 128, in <module>
# 1/0
# ZeroDivisionError: division by zero
raise
raise 关键字,手动抛出异常
使用raise的三种格式:
raise
raise 异常类型
raise 异常类型(说明信息)
def func1():
try:
print("else test ....")
1 / 0
except:
print("error")
raise
return
else:
print("else test end ...")
finally:
print("i am finally")
# return
func1()
"""
else test ....
error
i am finally
Traceback (most recent call last):
File "E:/scpythonProject/2022_4_30_模块与包/异常处理/异常处理.py", line 162, in <module>
func1()
File "E:/scpythonProject/2022_4_30_模块与包/异常处理/异常处理.py", line 151, in func1
1 / 0
ZeroDivisionError: division by zero
"""
print("start raise ....")
raise IndexError
print("end raise...")
"""
start raise ....
Traceback (most recent call last):
File "E:/scpythonProject/2022_4_30_模块与包/异常处理/异常处理.py", line 177, in <module>
raise IndexError
IndexError
"""
print("start raise ....")
raise IndexError("this is test")
print("end raise...")
"""
Traceback (most recent call last):
File "E:/scpythonProject/2022_4_30_模块与包/异常处理/异常处理.py", line 179, in <module>
raise IndexError("this is test")
IndexError: this is test
start raise ....
"""
在函数中,需要注意在try/except/finally使用return
•在finally中使用return,异常无法回溯
•在函数中的try/except语句使用return后,仍然会执行finally中的内容
def func1():
try:
print("else test ....")
1 / 0
except:
print("error")
raise Exception
else:
print("else test end ...")
finally:
print("i am finally")
func1()
# else test ....
# error
# i am finally
# Traceback (most recent call last):
# File "E:/scpythonProject/2022_4_30_模块与包/异常处理/异常处理.py", line 151, in func1
# 1 / 0
# ZeroDivisionError: division by zero
#
# During handling of the above exception, another exception occurred:
#
# Traceback (most recent call last):
# File "E:/scpythonProject/2022_4_30_模块与包/异常处理/异常处理.py", line 162, in <module>
# func1()
# File "E:/scpythonProject/2022_4_30_模块与包/异常处理/异常处理.py", line 154, in func1
# raise Exception
# Exception
在except中使用return,异常可以回溯
def func1():
try:
print("else test ....")
1 / 0
except:
print("error")
raise Exception
return
else:
print("else test end ...")
finally:
print("i am finally")
func1()
# else test ....
# error
# i am finally
# Traceback (most recent call last):
# File "E:/scpythonProject/2022_4_30_模块与包/异常处理/异常处理.py", line 151, in func1
# 1 / 0
# ZeroDivisionError: division by zero
#
# During handling of the above exception, another exception occurred:
#
# Traceback (most recent call last):
# File "E:/scpythonProject/2022_4_30_模块与包/异常处理/异常处理.py", line 162, in <module>
# func1()
# File "E:/scpythonProject/2022_4_30_模块与包/异常处理/异常处理.py", line 154, in func1
# raise Exception
# Exception
在finally中使用return,异常无法回溯
def func1():
try:
print("else test ....")
1 / 0
except:
print("error")
raise Exception
# return
else:
print("else test end ...")
finally:
print("i am finally")
return
func1()
# else test ....
# error
# i am finally
练习
def score_to_grade(score):
"""
根据学生成绩判断等级
:param score:输入学生成绩
:return:返回对应的等级
"""
try:
score = int(score)
except ValueError:
raise ValueError("您输入的数据不是整数!")
if score < 0 or score > 100:
raise ValueError("成绩范围不在[0,100]")
elif score >= 90:
return 'A'
elif 70 <= score < 90:
return 'B'
elif 60 <= score < 70:
return 'C'
else:
return 'D'
print("您的等级为:", score_to_grade('a'))