为什么要进行异常处理?
越复杂的程序设计中越容易出现异常,获得原谅比获得许可更容易。
异常发生后,程序就结束了并抛出了一个异常异常处理格式
# try:
# 可能发生异常的代码
# except:
# 异常处理代码
# except:处理所有异常
# except Type:处理指定类型的异常
# except type as data:获取异常信息
# except (Type1, Type2, Type3): 同时处理这三种异常,如果想获取异常数据,同样可以使用as语句,
# 也可以处理多个,继续添加类型即可
有如下实例:
student = {'name':'zs'}
try:
opt = int(input('请输入一个整数:'))
student['age']
except (KeyError, ValueError) as d:
print('ssds')
else:
print('没有发生异常')
print('Hello')
请输入一个整数:d
ssds
Hello
- 异常的处理模式
从最特殊到最一般处理,一旦处理了其中一个异常,后面的异常不会再处理
格式如下:
# 从最特殊到最一般处理,一旦处理了其中一个异常,后面的异常不会再处理
# try:
# pass
# except 异常类型1:
# pass
# except 异常类型2:
# pass
# except (异常类型3, 异常类型4, 异常类型5):
# pass
# except Exception as e:
# print(e)
# 定义这种方式捕捉异常时,一定要先写具体的异常,再写具有普遍性的异常。所有的异常,继承自Exception
# try:
# except:
# 发生异常执行
# else:
# 没有发生异常时执行
# finally:
# 有没有异常都会执行
# 可以只有try...finally语句
# finally 一般用来释放资源
随便举个例子:
try:
print('zs')
finally:
print("finally")
try:
num = int(input('请输入整数:'))
result = 8 / num
print(result)
except ValueError:
print("请输入一个整数")
except ZeroDivisionError:
print('除数不能为0')
except Exception as e:
print('未知错误%s'%e)
else:
print('正常执行')
finally:
print('执行完毕。。。不保证正确')
zs
finally
请输入整数:d
请输入一个整数
执行完毕。。。不保证正确
- 异常的传递
异常发生后,会传递给方法(函数)的调用者A。如果有捕捉到该异常,则按捕捉机制处理
如果A没有捕捉该异常,则会层层向上传递,最终会传递到python解析器,无法处理异常,此处就简单的终止程序
def fun1():
a = 0
print(10 / a)
def fun2():
# fun1()
try:
fun1()
except ZeroDivisionError:
print('除数为0')
fun2()
除数为0
这里异常是发生在fun1()函数里,而对于异常的处理却是在fun2()函数里
- 手动抛出异常:raise
不管程序有没有异常,我们就是任性,只要程序执行到raise语句就会抛出一个异常
实例如下:
def fun3():
print("Hello")
raise ZeroDivisionError()
fun3()
Traceback (most recent call last):
File "D:/Pycharm/day03/venv/Include/test.py", line 4, in
fun3()
File "D:/Pycharm/day03/venv/Include/test.py", line 3, in fun3
raise ZeroDivisionError()
ZeroDivisionError
- 自定义异常
所有异常类都可以继承自Exception类,
而类体中什么也不需要做,举个例子如下:
class ParamInvalidException(Exception):
pass
def login(username, pwd):
if len(username) < 6:
raise ParamInvalidException("用户名长度在1-6位之间")
if username != 'zhangsan':
raise ParamInvalidException('用户名错误')
print('登录成功')
try:
login('leiguang', '12345')
print('后继操作')
except ParamInvalidException as e:
print(e)
用户名错误
我们可以发现,自定义异常通常是配合raise使用的,而抛出的异常就是raise语句后面括号里的参数
- 程序发生异常了怎么办?
查看程序是否是可控的,不可控的化不管他,通常执行步骤如下:
# try:
# pass
# except Exception:
# # 先记录异常
# # 能处理就处理
# # 不能处理:raise