Python的异常处理

一、什么是异常

异常时程序发生错误的信号,程序一旦出错就会抛出异常
在pycharm编辑器中直接编辑一个变量名x-->run

x # 定义变量名
异常的三个特征:1、异常的追踪信息。2、异常的类型。3、异常的内容
# 运行结果如下: Traceback (most recent call last): # 文件的定位信息(1、异常的追踪信息) File
"D:/pycharm/oldboy_29/day034/day034_03异常.py", line 5, in <module> # 异常发生在哪行? x # (3、异常的内容) NameError: name 'x' is not defined # 异常的种类(2、异常的类型)
# 异常时程序发生错误的信号,程序一旦出错就会抛出异常,程序的运行随即终止,异常后的代码不会运行了
print("异常运行前的代码")
x
print("异常运行后的代码")

运行结果:
异常运行前的代码
Traceback (most recent call last):
File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 6, in <module>
x
NameError: name 'x' is not defined

二、为何处理异常

为了增强程序的健壮性,即便是程序运行过程中出错了,也不要终止程序
而是应该捕捉异常并处理:将出错的信息记录到日志里

三、如何处理异常

3.1、异常的来源

# 1)语法上的错误(SyntaxError)
if 1>3
    print("run...")

运行结果:
  File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 17
    if 1>3
         ^
SyntaxError: invalid syntax

针对语法错误的处理方式一:必须在程序运行前改正。
# 2)逻辑上的错误
# 逻辑错误示范一
print(x)
运行结果:
Traceback (most recent call last):
  File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 20, in <module>
    print(x)
NameError: name 'x' is not defined  # 引用一个不存在的名字x

# 逻辑错误示范二
1/0
运行结果:
Traceback (most recent call last):
  File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 21, in <module>
    1/0
ZeroDivisionError: division by zero   # 除数不能为0

# 逻辑错误示范三
int('abc')
运行结果:
Traceback (most recent call last):
  File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 22, in <module>
    int('abc')
ValueError: invalid literal for int() with base 10: 'abc'

# 逻辑错误示范四
dic = {'name':'lsj'}
dic['name']
运行结果:
Traceback (most recent call last):
  File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 24, in <module>
    dic['age']
KeyError: 'age'  # 引用了一个不存在的key

# 逻辑错误示范五
class Foo:
    pass
Foo.x
运行结果:
Traceback (most recent call last):
  File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 29, in <module>
    Foo.x
AttributeError: type object 'Foo' has no attribute 'x'  # 引用的属性不存在

# 逻辑错误示范六:

# TypeError:数字类型无法与字符串类型相加
1+’2’
# 逻辑错误示范七:
# ValueError:当字符串包含有非数字的值时,无法转成int类型
num=input(">>: ") #输入hello
int(num)

# 逻辑错误示范八: # IndexError:索引超出列表的限制 l=['egon','aa'] l[3]
# 针对逻辑错误的处理方式:有两种
逻辑错误处理方式一
# 方式一:错误发生的方式时可以预知的
# 猜年龄程序为例:
age = input('>>>:').strip() 
age = int(age)
if age > 18:
    print('猜大了')
elif age < 18:
    print('猜小了')
else:
    print('猜对了')

# 运行程序时输入数字
# >>>: 18
# 猜对了

# 程序运行时输入其他字符(这样的错误我们可以预知)
# >>>:aaaa
"""
Traceback (most recent call last):
  File "D:/pycharm/oldboy_29/day034/day034_03异常.py", line 38, in <module>
    age = int(age)
ValueError: invalid literal for int() with base 10: 'aaaa'
"""
# 猜年龄程序为例:
age = input('>>>:').strip()  # 输入的只要不是数字就会出错,所以在逻辑上进行处理
if age.isdigit():  # 使用if判断解决预知发生的错误
    age = int(age)
    if age > 18:
        print('猜大了')
    elif age < 18:
        print('猜小了')
    else:
        print('猜对了')
else:
    print("必须输入数字")
# 运行程序时输入数字
# >>>: 18
# 猜对了

# 程序运行时输入其他字符(这样的错误我们可以预知)
# >>>:aaaa
# 必须输入数字
逻辑错误处理方式二
# 方式二:错误发生的方式时无法预知的
"""以C/S架构为例,客户端发送请求,服务端没有接收,导致程序崩溃,我们再使用if判断就无法避免异常了
C<=============>S
"""
# 针对无法预知的异常,我们使用try语法(全部的语法罗列)
print('start...') try:
  # 有可能抛出异常的代码
  子代码块1
  子代码块2 # 如果此处有错误,同级后续代码不会运行,而是匹配异常类型去
  子代码块3 # 此处不能是回收资源的操作,要把回收资源的操作放进finally里,保证资源回收正常运行
except 异常类型1 as e: # as作用是把异常的类型去一个别名给e,我们能可以再后期对这个e进行操作:打印或者记录到日志里。 pass
except 异常类型2 as e:
  pass
...
else:
  如果被检测的子代码块没有异常发生,则会执行else的子代码
finally:
  无论被检测的子代码块有无异常发生,都会执行finally的子代码
print('end...')
# try语法变形一:
try:
  子代码块1
  子代码块2
  子代码块3
except  异常类型1 as e:  
    pass
# try语法变形二:
try:
  子代码块1
  子代码块2 
  子代码块3 
finally:
  无论被检测的子代码块有无异常发生,都会执行finally的子代码
注意:上面的做法降低了代码的可读性(所以能少用就少用)
# 使用try来演示可预见异常
# 用法一:
print('start...')
try:
    print('1111')
    l = ['aaa','bbb']
    l[3]  # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
    print('2222')
    xxx
    print('3333')
    dic = {'a':1}
    dic['a']
except IndexError as e:
    # print('异常已经被处理')
    print('异常的信息:',e)
print('end...')
运行结果:

start...
1111
异常的信息: list index out of range  # 列表索引超出范围
end...

# 注意用法一:使用其他异常代替IndexError异常
print('start...') try: print('1111') l = ['aaa','bbb'] l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了 print('2222') xxx print('3333') dic = {'a':1} dic['a'] # except IndexError as e: # 索引异处理 except ValueError as e: # 如果我们使用ValueError异常接收,由于代码是逐行向下运行,遇到哪个异常就报哪个异常 print('异常的信息:',e) print('end...') 运行结果: start... 1111 Traceback (most recent call last): File "D:/pycharm/oldboy_29/day034/day034_04.py", line 11, in <module> l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了 IndexError: list index out of range
# 用法二
print('start...')
try:
    print('1111')
    l = ['aaa','bbb']
    # l[3]  # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
    print('2222')
    xxx
    print('3333')
    dic = {'a':1}
    dic['a']
except IndexError as e:  # 索引异处理
    print('异常的信息:',e)
except NameError as e:
    print('异常的信息:', e)
print('end...')
运行结果

start...
1111
2222
异常的信息: name 'xxx' is not defined
end...

# 这里有个问题就是print('异常的信息:',e)有重复代码的出现

# 用法三:针对多种异常的合并
print('start...')
try:
    print('1111')
    l = ['aaa','bbb']
    # l[3]  # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
    print('2222')
    # xxx
    print('3333')
    dic = {'a':1}
    dic['a']
    dic['bb']
except (IndexError,NameError) as e:  # 以元组形式加入到一行里
    print('异常的信息:',e)
except KeyError as e:
    print('字典的key不存在:',e)
print('end...')
运行结果:

start...
1111
2222
3333
字典的key不存在: 'bb'
end...

# 用法四:万能异常
print('start...')
try:
    print('1111')
    l = ['aaa','bbb']
    # l[3]  # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
    print('2222')
    # xxx
    print('3333')
    dic = {'a':1}
    dic['a']
    dic['bb']
# except (IndexError,NameError) as e:  # 以元组形式加入到一行里
#     print('异常的信息:',e)
# except KeyError as e:
#     print('字典的key不存在:',e)
except Exception as e:
    print('所有异常都可以匹配的到')
print('end...')
# 用法五:else不能与try配合使用会报语法错误
print('start...')
try:
    print('1111')
    l = ['aaa','bbb']
    # l[3]  # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
    print('2222')
    # xxx
    print('3333')
    dic = {'a':1}
    dic['a']
    dic['bb']
# except Exception as e:
#     print('所有异常都可以匹配的到')
else:
    print('===>')
print('end...')
运行结果:
  File "D:/pycharm/oldboy_29/day034/day034_05.py", line 17
    else:
    ^
SyntaxError: invalid syntax
# 用法六:try不能与finally配合使用
#
print('start...')
try:
    print('1111')
    l = ['aaa','bbb']
    l[3]  # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
    print('2222')
    xxx
    print('3333')
    dic = {'a':1}
    dic['a']
    dic['bb']
finally:  # finally不处理异常,无论是否发生异常都会执行finally的子代码
    print('try与fianlly配合===>此处应该把被检测代码中回收系统资源的代码放到这里')
print('end...')
运行结果:

Traceback (most recent call last):
start...
File "D:/pycharm/oldboy_29/day034/day034_05_01.py", line 8, in <module>
1111
l[3] # 遇到异常IndexError,该行代码代码同级别的后续代码不会运行了
try与fianlly配合
IndexError: list index out of range

 

 

 

 

posted @ 2020-05-16 00:25  思江  阅读(288)  评论(0编辑  收藏  举报