Python——异常处理机制

Python异常与异常处理机制

Python使用称为异常的特殊对象来管理程序执行期间发生的错误(Python中一切皆对象,包括异常也是对象)。每当发生程序错误,都会创建一个异常对象。如果编写了处理该异常的代码,程序将继续运行;但是如果未编写代码对异常进行处理,程序将停止并显示traceback,其中包含有关异常的报告

异常处理是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况,即超出程序正常执行流程的某些特殊条件。异常处理机制是使用 try-except 代码块处理异常,try-except 代码块让Python执行指定的操作,同时告诉Python发生异常时怎么办。使用try-except 代码块时,即便出现异常,程序也将继续运行,同时显示你编写的友好的错误消息,而不是令用户迷惑的traceback

Python提供了两个非常重要的功能来处理程序在运行中出现的异常和错误。经常使用的是try…except语句,拓展一下就是try-except-else-finally,另一个是断言,即assert

针对 Traceback 的解读

Traceback 是 Python 错误信息的报告,当你的程序导致异常时,Python 将打印 Traceback 以帮助你知道哪里出错了。虽然 Python 的 Traceback 提示信息看着挺复杂,但是里面存在丰富的信息,可以帮助你诊断和修复代码中引发异常的原因,以及定位到具体哪个文件的哪行代码出现的错误,这样有助于我们编写对应的异常处理代码来捕获异常,并给出合适的错误提示信息。所以说学会看懂 Traceback 信息是非常重要的

下面给出一个案例进行分析,这是一种导致Python引发异常的简单错误:除0

# calculate.py文件的内容
def divide(a, b):	# 进行除法运算的函数
    return a / b

# main.py文件的内容
from calculate import divide

divide(5, 0)

# 抛出异常:
"""
Traceback (most recent call last):
  File "C:\编程\Python代码\test\main.py", line 3, in <module>
    divide(5, 0)
  File "C:\编程\Python代码\test\calculate.py", line 2, in divide
    return a / b
ZeroDivisionError: division by zero
"""
  • 错误输出的最后一行一般会告诉你引发了什么类型的异常,以及关于该异常的一些相关信息,所以看错误信息的最后一行就能获知到错误的原因
    • 在上述 traceback 中,最后一行指出的错误 ZeroDivisionError 就是一个异常对象,并且给出了具体的描述 division by zero,即表示因为除0,导致程序抛出该异常
  • 错误输出的前面几行的阅读顺序应该是由下而上的,因为越往上,离抛出异常的实际位置越远,越难定位到抛出异常的代码
  • 这一部分要每连续两行为一组进行阅读。其中每组的第1行会告诉你是在哪个文件的、哪个函数的、哪一行出错了,也就是会更直接的告诉你错误发生的位置;每组的第2行会把报错的那一行代码显示出来
  • 比如在程序里A函数调用了B函数,然后B函数调用了C函数,而C函数报错了,那么 traceback 中的前几行从下至上的顺序来看,会先显示C函数的信息,再显示B函数的信息,再显示A函数的信息,而且每一个函数的信息都是按两行来组织的,其中第1行展示位置,第2行展示代码
    • 在上述 traceback 中,前面几行中的最后一行定位的位置为位于 calculate.py 文件中的第2行,并且位于 divide 函数代码块中,具体抛出异常的代码为"return a / b"
    • 然后我们看上一行,定位的位置为位于 main.py 文件中的第3行,并且位于引入模块的代码中,具体抛出异常的代码为"divide(5, 0)"
  • 最上面第一行的内容是固定不变的,始终Traceback (most recent call last)”,可以忽略

try-except-else-finally

  • try:正常情况下,程序计划执行的语句
  • except:程序异常时执行的语句
  • else:程序无异常,即try段代码正常执行后会执行该语句
    • 当try语句的相关代码中的return,continue或break语句被执行时,else语句将被忽略
  • finally:不管有没有异常,都会执行的语句
    • 具体来说,当try,except或else语句的相关代码中存在某些跳转语句时,比如break,continue和return,与finally语句相关的代码将在这些跳转语句执行之前被执行
    • 在处理 Python 异常的过程中,一些代码需要始终被执行,无论是否有 Python 异常被抛出,或 Python 异常是否被处理。使用finally语句可以达成上述目标,该语句之后的代码通常与清理工作有关,比如,关闭打开的文件

运行逻辑1:首先运行try中的代码块,当出现异常时,终止try中代码块的执行,立即执行except中的代码块,最后执行finally中的代码块

try:
    print('输出:我是try1')
    a = 5 / 0
    print('输出:我是try2')

except :
    print('输出:我是except')

else :
    print('输出:我是else')

finally :
    print('输出:我是finally')

# 输出结果:
"""
输出:我是try1
输出:我是except
输出:我是finally
"""

运行逻辑2:首先运行try中的代码块,当执行完毕后,代码始终没有抛出异常,继续执行else中的代码块,最后执行finally中的代码块

try:
    print('输出:我是try1')
    a = 5 / 1
    print('输出:我是try2')

except :
    print('输出:我是except')

else :
    print('输出:我是else')

finally :
    print('输出:我是finally')

# 输出结果:
"""
输出:我是try1
输出:我是try2
输出:我是else
输出:我是finally
"""

运行逻辑3:函数中,如果finally语句的相关代码中包含了return语句,那么该return语句所返回的值(包括空值None),将取代try,except或else语句相关代码中的返回值

因为finally中的代码块在设定上必须执行:

  • 在try中的代码块return之前,会执行finally中的语句,try中的return被忽略了,最终返回的值是finally中return值
  • try中的代码块没有return语句,执行完毕后,会继续执行else中的语句,在else中的代码块return之前,执行finally中的语句,else中的return被忽略了,最终返回的值是finally中return值
  • try中的代码块中抛出异常,被except捕获,在except中的代码块return之前,执行finally中的语句,except中的return被忽略了,最终返回的值是finally中return值
def test():
    try:
        print('输出:我是try1')
        a = 5 / 0
        print('输出:我是try2')
        return 1

    except :
        print('输出:我是except1')
        return 2
        print('输出:我是except2')

    else :
        print('输出:我是else')
        return 3

    finally :
        print('输出:finally')
        return 4

num = test()
print(num)

# 输出结果:
"""
输出:我是try1
输出:我是except1
输出:finally
4
"""


def test():
    try:
        print('输出:我是try1')
        a = 5 / 1
        print('输出:我是try2')
        return 1

    except :
        print('输出:我是except')
        return 2

    else :
        print('输出:我是else')
        return 3

    finally :
        print('输出:finally')
        return 4

num = test()
print(num)

# 输出结果:
"""
输出:我是try1
输出:我是try2
输出:finally
4
"""


def test():
    try:
        print('输出:我是try1')
        a = 5 / 1
        print('输出:我是try2')
        # return 1

    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值