什么是异常?
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。一般情况下,在Python无法正常处理程序时就会发生一个异常。异常是Python对象,表示一个错误。当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
两种表现
- 自己造孽:写错代码了!错误也是一种异常;程序都运行不起来!
- 程序运行过程中,在某些特定条件下,不合适的数据引起程序出现错误导致程序崩溃
为什么要处理异常
当程序在运行过程中,由于用户的误操作或者不合适的数据引发的程序错误,让代码自己处理并保证程序的正常执行。而不至于因为错误导致程序崩溃!提高代码的健壮性!
python标准异常
异常名称 | 描述 |
---|---|
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行 |
Exception | 常见异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
AttributeError | 没有这个属性 |
EOFError | 没有內键输入 |
EnvironmentError | 操作系统错误的基类 |
ImportError | 导入模块错误 |
IndexError | 序列中没有此索引 |
NameError | 未声明初始化对象 |
SyntaxError | 语法错误 |
IndentationError | 缩进错误 |
TabError | tab和空格混用 |
TypeError | 类型错误,对类型无效的操作 |
ValueError | 传入无效的操作 |
怎么处理异常?
捕捉异常可以使用try/except语句。
try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。
如果你不想在异常发生时结束你的程序,只需在try里捕获它。
语法:
以下为简单的try....except...else的语法:
try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生
finally: # 不论是否出现异常,都要在try执行完成之后执行的代码
<最终的扫尾工作>
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
- 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
- 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
- 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
基础操作
- 不捕获异常
try:
可能出现异常的代码
except:
出现异常之后要执行的代码
- 捕获具体异常
try:
可能出现异常的代码
except Exception as e:
出现异常之后执行的代码
实例
- 1try-except直接处理异常【可以处理任何异常—不能定位具体是什么异常
print("*****************************")
print("\t\t计算器")
print("******************************")
try:
num1 =int(input("请输入第一个数据:"))
except:
print("输入不合法!")
else:
print("%s"%num1)
以上方式try-except语句捕获所有发生的异常。但这不是一个很好的方式,我们不能通过该程序识别出具体的异常信息。因为它捕获所有的异常。
- 2 try-except [异常信息] 【可以处理指定的异常】
print("*****************************")
print("\t\t计算器")
print("******************************")
try:
num1 =int(input("请输入第一个数据:"))
except ValueError as e:
print("输入不合法!%s"%e)
else:
print("%s"%num1)
- 3 使用except而带多种异常类型
print("~ * ~ * ~ * ~ * ~ * ~ * ~ * ~")
print("\t\t1.文件操作——读取数据")
print("~ * ~ * ~ * ~ * ~ * ~ * ~ * ~")
try:
c = int(input("请输入您的选项:")) #ValueError
if c == 1:
f = open("d:/test.txt") # FileNotFoundError
print(f.read())
f.close()
except (ValueError, FileNotFoundError) as e:
print("程序中出现了错误:%s" % e)
不推荐
使用多个except
如果是同一个级别的异常,根据try中出现异常的顺序进行捕获
如果不是同一个级别的异常,先捕获具体的【子类异常】,再捕获抽象的【父类异常】
print("~ * ~ * ~ * ~ * ~ * ~ * ~ * ~")
print("\t\t1.文件操作——读取数据")
print("~ * ~ * ~ * ~ * ~ * ~ * ~ * ~")
try:
c = int(input("请输入您的选项:")) #ValueError
if c == 1:
f = open("d:/test.txt") # FileNotFoundError
print(f.read())
f.close()
except ValueError as e:
print("选项输入错误:%s" % e)
except FileNotFoundError as e:
print("文件读取错误:%s" % e)
except Exception as e:
print("程序中出现了未知错误:%s" % e)
print("程序执行完成..")
- 4 自定义异常
异常— 一种对象
自定义异常 – 一种自定义类型
自定义类型[异常] – 参考标准异常(继承Exception)—自定义异常(继承Exception - 5 主动抛出异常
在开发的过程中,主动出现一种错误,将错误抛出给程序告诉程序出错了。通过raise关键字,抛出一个异常 - 6 自定义异常,就是为了专门抛出错误的,抛出错误,就是严重警告这里出现了什么问题
首先-代码执行过程中,出现了异常【系统标准异常】【信息不是很明白】
捕获系统异常,创建一个自定义异常
抛出自定义异常【自定义异常】【信息明确的错误】
自定义异常的目的:转换异常信息,将不明确的异常信息转换成更加精确的异常信息
V1.0 定义一个自定义异常,和抛出异常的语法
# 定义一个自定义异常
# class MyError(Exception):
# # 将错误描述信息,在初始化函数中,交给父类
# def __init__(self, msg):
# Exception.__init__(self, msg)
#
# x = input("请输入您的信息:")
# raise MyError("不好意思,我就是要出错....")
# print("您输入了:%s" % x)
class NumError(Exception):
def __init__(self):
Exception.__init__(self, "这里必须要输入数字,但是您输入了非法字符")
'''
# V2.0
try:
num = int(input("请输入一个数值:"))
except ValueError: # 捕获系统异常
raise NumError()
else:
print("用户输入了:%d" % num)
print("程序执行完成")
'''
# 3.0
# 定义了一个输入数值的函数:开发人员A开发的代码
def inputNumber():
try:
num = int(input("请输入一个数值:"))
except ValueError: # 捕获系统异常
raise NumError()
else:
print("用户输入了:%d" % num)
return num
# 开发人员B在开发的代码
# 调用输入数值的方法
try:
num = inputNumber()
except NumError as e:
print("出现了异常信息:%s" % e)
- 7 Finally
try:
f = open("d:/test.txt", "w")
f.write(["a", "b"])
except FileNotFoundError as e:
print("文件操作失败")
finally:
f.close()#"最后总是要执行我"