异常处理

异常处理

1、什么是异常

异常指的是程序运行发生错误的信号,程序在运行工程中一旦出错,就会抛出异常,程序也会随着结束掉。

print('start')
[1, 2, 3][100]
print('stop')
# start
# IndexError: list index out of rang
# 运行到[1,2,3][100]遇到索引错误,抛出错误信息,程序立即终止,之后的'top'不会打印

1.1、异常处理的三个特征

  1. 异常处理的追踪信息

2)异常的类/类型

3)异常的内容,异常的值

2、为何要处理异常

为了增强程序的健壮性(robust),本来程序一旦出现异常就整体结束掉了,有了异常处理以后,在被检测的代码块出现异常时,被检测的代码块中异常发生位置之后的代码将不会执行,取而代之的是执行匹配异常的except子代码块,其余代码均正常运行,我们也可以将异常信息记录到日志内。

3、如何处理异常

异常总体可以分为两种:语法错误和逻辑错误

3.1 语法错误(SyntaxError)

语法错误是一种低级的错误,我们在写代码的时候应尽量避免。

处理方法:在程序运行前就改正

如:

#if判断,判断条件后缺少冒号:
if 3>1
    print('run...')
    
#SyntaxError: invalid syntax    

#在运行前改正
if 3>1:
    print('run...')

3.2 逻辑上的错误

每个人的逻辑不可能永远一丝不漏,都可能出现纰漏,所以这种逻辑上的错误我们可能经常遇到,而且这种错误我们事先不知道。

#1)
print(x)
#NameError: name 'x' is not defined

#2)
l=[1,2]
print(l[111])
#IndexError: list index out of range

#3)
1/0
#ZeroDivisionError: division by zer

#4)
int('abc')
#ValueError: invalid literal for int() with base 10: 'abc'

#5)
dic={'age':18}
print(dic['sex'])
#KeyError: 'sex'

#6)
class Foo:
    pass
Foo.x
#AttributeError: type object 'Foo' has no attribute 'x'

针对逻辑上的异常处理方式可以分为两种:

3.2.1 如果错误是可以预知的,使用if判断解决

拿猜年龄小程序来说,因为我们无法控制用户的输入,当输入不是数字时就会报错,但是这种错误我们可以预知到,使用if判断就能将这种错误规避掉:

age=input('猜猜我的年龄,请输入你猜测的年龄: ').strip()
#加入if判断,根据if判断结果选择运行的代码,避免了报错
if not age.isdigit():
    print('您的输入有误,年龄的是数字,请输入数字')
else:
    age=int(age)
    if age<18:
        print('猜小了哦!')
    elif age>18:
        print('猜大了哦!')
    else:

3.2.1 如果错误是我们不能预知,我们就得使用Try/except 异常处理机制来解决

基本的语法为:

# print('start...')
# try:
#     # 有可能会抛出异常的代码
#     子代码1
#     子代码2
#     子代码3
# except 异常类型1 as e:
#     pass
# except 异常类型2 as e:
#     pass
# ...
# else:
#     如果被检测的子代码块没有异常发生,则会执行else的子代码
# finally:
#     无论被检测的子代码块有无异常发生,都会执行finally的子代码
#
# print('end...')

用法一:

print('start')
try:
    print('1')
    l=['aaa','bbbb']
    l[3]

    print('2')
    xxx

    print('3')
    dic={'egon':18}
    dic['tank']
except IndexError as e:
    print('异常信息:',e)
'''
start
1
异常信息: list index out of range'''
# 不会打印2,发生IndexError,之后的代码不在运行,运行except的子代码

用法二:

跟if判断有点相似,第一中异常不满足,继续往下走,其他异常满足,其他异常下的子代码:

try:
    print('1')
    l=['aaa','bbbb']
    # l[3]

    print('2')
    xxx

    print('3')
    dic={'egon':18}
    dic['tank']
except IndexError as e:   
    print('异常信息:',e)
except NameError as e:
    print('异常信息:',e)
'''
start
1
2
异常信息: name 'xxx' is not defined'''

用法三:

将可能出现的异常类型放到 except后的元组类,类似于or,满足其一,执行子except的子代码:

print('start')
try:
    print('1')
    l=['aaa','bbbb']
    # l[3]

    print('2')
    # xxx

    print('3')
    dic={'egon':18}
    dic['tank']
except (IndexError,NameError,KeyError) as e:
    print('异常信息:',e)

'''
start
1
2
3
异常信息: 'tank' '''

用法四:

except后加else,注意else不能单独与try配合使用,必须要搭配except

,必须放在except之后。只有在被检测的代码块没有触发任何异常的情况下才会执行else的子代码块,

print('start...')

try:
    print('1')
    print('2')
    print('3')

except Exception as e:  # 万能异常
    print('所有异常都可以匹配的到')
else:
    print('====>')

print('end....')
'''
start...
1
2
3
====>
end....'''

用法五:

finally可以单独与try配合使用,无论被检测的代码块是否触发异常,都会执行finally的子代码块,因此通常在finally的子代码块做一些回收资源的操作,比如关闭打开的文件、关闭数据库连接等

f=None
try:
    f=open(‘db.txt’,'r',encoding='utf-8')
    s=f.read().strip()
    int(s)  # 若字符串s中包含非数字时则会触发异常ValueError
    # f.close() # 若上面的代码触发异常,则根本不可能执行到此处的代码,应该将关闭文件的操作放到finally中
finally:
    if f: # 文件存在则f的值不为None
        f.close()
原文地址:https://www.cnblogs.com/zhangtieshan/p/12714350.html