python:异常
异常:
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
常见异常类:
我们可以看到python的异常有个大基类。然后继承的是Exception。所以我们自定义类也必须继承Exception。
抛出异常:
格式:
raise
异常名称(‘异常描述’)
在开发中,除了代码执行出错 Python 解释器会抛出异常之外, 还可以根据应用程序 特有的业务需求主动抛出异常。Python 中提供了一个 Exception
异常类,在开发时,如果满足 特定业务需求时,希望 抛出异常,可以:
- 创建 一个
Exception
的 对象, 或继承自Exception
的对象 - 使用
raise
关键字 抛出 异常对象
示例:
提示用户 输入密码,如果 长度少于 8,抛出 异常。
def input_password():
# 1. 提示用户输入密码
pwd = input("请输入密码:")
# 2. 判断密码长度,如果长度 >= 8,返回用户输入的密码
if len(pwd) >= 8:
return pwd
# 3. 密码长度不够,需要抛出异常
# 1> 创建异常对象 - 使用异常的错误信息字符串作为参数
ex = Exception("密码长度不够")
# 2> 抛出异常对象
raise ex
try:
user_pwd = input_password()
print(user_pwd)
except Exception as result:
print("发现错误:%s" % result)
>>>请输入密码:>? 123
发现错误:密码长度不够
该例子中利用raise
抛出异常,利用try...exception...
捕捉异常。
捕获异常:
处理特殊情况有两种理念,第一种理念是三思而后行(LBYJ), 第二种理念是请求原谅比获得许可更容易(EAFP).
LBYJ:
想要避免异常发生,则要使用积极的条件去测试,这种代码中会有很多的if语句。
if y != 0:
ratio = x / y
else:
..,do something else...
EAFP:
不需要花额外的时间来维护每一个可能发生的异常,只要异常发生时有一个能处理的机制就行,特点代码中有很多try...except..
语句。
try:
ratio = x / y
except ZeroDivisionError:
...do somthing else...
try…except…else:
try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
- 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
- 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
- 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
使用相同的except语句来处理多个异常信息:
try:
正常的操作
......................
except(Exception1[, Exception2[,...ExceptionN]]]):
发生以上多个异常中的一个,执行这块代码
......................
else:
如果没有异常执行这块代码
示例一:
try:
f = open('sample.txt')
exception IOError as e:
print('Unable open the file: ', e)
e表示抛出异常的实例,输出并显示详细的错误消息。
示例二:
age = -1
while age <= 0:
try:
age = int(input('Enter your age: '))
if age <= 0:
print('Your age must be positive')
except ValueError:
print('That is invalid age specification')
except EOFError:
print('There is an unexpected error reading input.')
raise
该例子中为不同的错误提供不同的相应,如果在try
中运行int
或input
中发生异常,age就不会赋值,while循环会继续。另外在捕获EOFError
异常时,使用raise
语句且没有其他后续参数来重新抛出相同的目前正在处理的异常。使得我们对异常能提供自己的响应, 然后中断while循环冰箱上传播。
异常捕获完整语法:
try:
# 尝试执行的代码
pass
except 错误类型1:
# 针对错误类型1,对应的代码处理
pass
except 错误类型2:
# 针对错误类型2,对应的代码处理
pass
except (错误类型3, 错误类型4):
# 针对错误类型3 和 4,对应的代码处理
pass
except Exception as result:
# 打印错误信息
print(result)
else:
# 没有异常才会执行的代码
pass
finally:
# 无论是否有异常,都会执行的代码
print("无论是否有异常,都会执行的代码")
try:
num = int(input("请输入整数:"))
result = 8 / num
print(result)
except ValueError:
print("请输入正确的整数")
except ZeroDivisionError:
print("除 0 错误")
except Exception as result:
print("未知错误 %s" % result)
else:
print("正常执行")
finally:
print("执行完成,但是不保证正确")