← 返回首页
Python3基础教程(四十三)
发表时间:2022-04-10 11:27:12
异常处理

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