1.异常处理结构
异常是指程序在运行过程中出现的意外情况。与Java类似,python的异常处理使用了try/except语句结构。
语法如下:
try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了'name'异常
except <名字> as <数据>:
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生
finally:
<语句> #无论是否发生异常都必须执行的语句
学过Java同学对以上异常处理结构一点也不陌生。
实例:
# -*- coding: utf-8 -*-
# @Time : 2022/4/10 10:49
# @File : exceptiondemo.py
# @Software : PyCharm
try:
print('-----try open file---')
open('haha.txt', 'r')
print('-----open success---')
r = 10 / 2
print('result:', r)
except IOError as e:
print('IOException:', e)
except ZeroDivisionError as e:
print('ZeroDivisionError:', e)
else:
print('program is ok!')
finally:
print('must be do something...')
如果程序所在目录不存在haha.txt,则出现以下结果:
-----try open file---
IOException: [Errno 2] No such file or directory: 'haha.txt'
must be do something...
2.异常捕获
python所有的异常类型都继承自BaseException,因此与Java类似也要求必须先捕获子类异常再捕获父类异常,否则父类异常会把子类异常“一网打尽”。
实例:
try:
print('-----try open file---')
open('test.txt', 'r')
print('-----open success---')
r = 10 / 0
print('result:', r)
except BaseException as e:
print('BaseException:', e)
except IOError as e:
print('IOException:', e)
except ZeroDivisionError as e:
print('ZeroDivisionError:', e)
else:
print('program is ok!')
finally:
print('must be do something...')
后面的IOError和ZeroDivisionError 永远也捕获不到异常。与Java不同的是编译时不会报错。
运行结果:
-----try open file---
-----open success---
BaseException: division by zero
must be do something...
3.抛出异常
python中使用raise语句抛出一个错误的实例。
实例:
# -*- coding: utf-8 -*-
# @Time : 2022/4/10 10:49
# @File : exceptiondemo.py
# @Software : PyCharm
# 自定义自己的异常类
class MyError(ValueError):
pass
try:
print('-----try open file---')
open('test.txt', 'r')
print('-----open success---')
r = 10 / 2
print('result:', r)
raise MyError('MyError appear...')
except IOError as e:
print('IOException:', e)
except ZeroDivisionError as e:
print('ZeroDivisionError:', e)
except BaseException as e:
print('BaseException:', e)
else:
print('program is ok!')
finally:
print('must be do something...')
运行结果:
-----try open file---
-----open success---
result: 5.0
BaseException: MyError appear...
must be do something...
4.调用栈
如果错误没有被捕获,它就会一直往上抛,最后被Python解释器捕获,打印一个错误信息,然后程序退出。
实例;
def div(x,y):
return x/y
def fn(x,y):
return div(x,y)
def main():
x = 10
y = 0
result = fn(x,y)
print(result)
main()
运行结果:
Traceback (most recent call last):
File "G:\python_lesson\moduledemo\exceptiondemo2.py", line 21, in <module>
main()
File "G:\python_lesson\moduledemo\exceptiondemo2.py", line 18, in main
result = fn(x,y)
File "G:\python_lesson\moduledemo\exceptiondemo2.py", line 11, in fn
return div(x,y)
File "G:\python_lesson\moduledemo\exceptiondemo2.py", line 7, in div
return x/y
ZeroDivisionError: division by zero
与Java不同的是python允许跨越多层调用,比如函数main()调用fn(),fn()调用div(),结果div()出错了,这时,只要main()捕获到了,就可以处理。
改写如下:
def div(x, y):
return x / y
def fn(x, y):
return div(x, y)
def main():
x = 10
y = 0
result = 0
try:
result = fn(x, y)
except BaseException as e:
print('BaseException:', e)
finally:
print(result)
main()
运行结果:
BaseException: division by zero
0