2021-05-16

异常机制本质

异常指程序运行过程中出现的非正常现象,例如用户输入错误、除数为零、需要处理的文件不存在、数组下标越界等。

所谓异常处理,就是指程序在出现问题时依然可以正确的执行剩余的程序,而不会因为异常而终止程序执行。

python中,引进了很多用来描述和处理异常的类,称为异常类。异常类定义中包含了该类异常的信息和对异常进行处理的方法。下面较为完整的展示了 python 中内建异常类的继承层次:

 

python 中一切都是对象,异常也采用对象的方式来处理。处理过程:

1. 抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给解释器。

2. 捕获异常:解释器得到该异常后,寻找相应的代码来处理该异常

异常解决的关键:定位

当发生异常时,解释器会报相关的错误信息,并会在控制台打印出相关错误信息。我们 只需按照从上到下的顺序即可追溯(Trackback)错误发生的过程,最终定位引起错误的那一 行代码。

【示例】追溯异常发生的过程

def a():
    print("run in a() start! ")
    num = 1/0
    print("run in a() end! ")
def b():
    print("run in b() start!")
    a()
    print("run in b() end! ")
def c():
    print("run in c() start!")
    b()
    print("run in c() end! ")
print("step1")
c()
print("step2")

控制台打印结果:

step1

run in c() start!

run in b() start!

run in a() start!

Traceback (most recent call last):

  File "D:\study\PycharmProjects\mypro01\mypy13.py", line 14, in <module>

    c()

  File "D:\study\PycharmProjects\mypro01\mypy13.py", line 11, in c

    b()

  File "D:\study\PycharmProjects\mypro01\mypy13.py", line 7, in b

    a()

  File "D:\study\PycharmProjects\mypro01\mypy13.py", line 3, in a

    num = 1/0

ZeroDivisionError: division by zero

Process finished with exit code 1

 

try...一个 except 结构

try...except 是最常见的异常处理结构。结构如下:

try:

      被监控的可能引发异常的语句块

except BaseException [as e]:

      异常处理语句块

try块包含着可能引发异常的代码,except则用来捕捉和处理发生的异常。执行的时候,如果try块中没有引发异常,则跳过except块继续执行后续代码;执行的时候,如果try块中发生了异常,则跳过try块中的后续代码,跳到相应的except块中处理异常;异常处理 完后,继续执行后续代码。

·遇到异常的执行顺序:

try:

    print("step1")

    a = 3/0

    print("step2")

except BaseException as e:

    print("step3")

    print(e)

print("step4")

如上的执行结果是:

step1

step3

division by zero

step4

程序执行到引发异常的语句时,直接掉到except异常处理语句块进行处理;处理完毕后,继续执行下面的程序。

try:

    print("step1")

    a = 3/2

    print("step2")

except BaseException as e:

    print("step3")

    print(e)

print("step4")

如上代码的执行结果是:

step1

step2

step4

try语句块没有发生异常,则正常执行完try块后跳过except异常处理语句块,继续往 下执行。

【示例】循环输入数字,如果不是数字则处理异常;直到输入 88,则结束循环。

while True:

    try:

        x = int(input("请输入一个数字:"))

        print("您入的数字是",x)

        if x==88:

            print("退出程序")

            break

    except:

        print("异常:输入的不是一个数字")

执行结果:

请输入一个数字:77

您入的数字是 77

请输入一个数字:cc

异常:输入的不是一个数字

请输入一个数字:--

异常:输入的不是一个数字

请输入一个数字:88

您入的数字是 88

退出程序

try...多个 except 结构

try...多个 except 结构如下:

try:

      被监控的、可能引发异常的语句块

except Exception1:

      处理 Exception1 的语句块

except Exception2:

      处理 Exception2 的语句块

...

except BaseException:

      处理可能遗漏的异常的语句块

【示例】try...多个 except 结构

try:

    a = input("请输入被除数:")

    b = input("请输入除数:")

    c = float(a)/float(b)

    print(c)

except ZeroDivisionError:

    print("异常:除数不能为 0")

except TypeError:

    print("异常:除数和被除数都应该为数值类型")

except NameError:

    print("异常:变量不存在")

except BaseException as e:

    print(e)

    print(type(e))

执行结果(异常):                     执行结果(正常):

请输入被除数:30                        请输入被除数:30

请输入除数:0                             请输入除数:10

异常:除数不能为 0                     3.0

try...except...else 结构

try...except...else 结构增加了“else块”。如果 try 块中没有抛出异常,则执行else块。如果try块中抛出异常,则执行except块,不执行else块。

【示例】try...except...else 结构执行测试

try:

    a = input("请输入被除数:")

    b = input("请输入除数:")

    c = float(a)/float(b)

except BaseException as e:

    print(e)

else:

    print("除的结果是:",c)

执行结果(抛出异常):                   执行结果(正常执行):

请输入被除数:30                             请输入被除数:30

请输入除数:0                                  请输入除数:10

float division by zero                         除的结果是: 3.0

try...except...finally 结构

try...except...finally结构中,finally块无论是否发生异常都会被执行;通常用来释放try块中申请的资源。

try:

    a = input("请输入一个被除数:")

    b = input("请输入一个除数:")

    c = float(a)/float(b)

except BaseException as e:

    print(e)

else:

    print(c)

finally:

    print("我是 finally 中的语句,无论发生异常与否,都执行!")

print("程序结束!")

执行结果:

请输入一个被除数:30

请输入一个除数:0

float division by zero

我是 finally 中的语句,无论发生异常与否,都执行!

程序结束!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值