【Python】你真的了解异常吗?-别再说你不了解异常啦
文章目录
主要内容:
理解异常的基本概念
掌握Python中异常的基本使用方法
认识异常
在我们前面经常提到 “程序运行出错” 这样的概念. 实际上, 这是Python解释器抛出了一个 异常
异常的基本概念
我们故意将 print 敲错, 解释器抛出了一个 NameError 异常
a = 10
prin(a) # NameError: name 'prin' is not defined
我们故意访问一个下标越界的列表, 解释器抛出了一个 IndexError 异常
a = [1,2,3]
print(a[100]) #IndexError: list index out of range
我们故意打开一个不存在的文件, 解释器抛出一个FileNotFoundError 异常
a = open('Z:/zzz.txt','r')
#FileNotFoundError: [Errno 2] No such file or directory: 'Z:/zzz.txt'
总结:
这里我们要把Python的异常和C++/Java的异常做一个区分:
因为Python是解释执行的, 所以语法错误和执行逻辑出现问题导致的错误都被Python统一成了异常.
而C++和Java会预先对代码进行编译. 如果语法出错, 在编译期就能检查出来. 因此C++和Java的异常只涵盖运行时的错误.
类比 Linux 的信号机制
异常机制的意义
异常机制归根结底是想办法帮我们简化代码的错误处理逻辑.
C语言如何处理”异常“
调用一个函数, 有可能会调用失败. C语言中通常使用函数返回一个错误的值的方式来判定函数的成功失败.-> 因此每个函数调用完成, 往往需要检查一下函数都返回值.
每调用一个函数, 都要围绕这个函数写一大堆处理错误情况的逻辑, 导致处理正常逻辑的代码, 和处理异常
逻辑的代码混淆在一起.
通过异常处理机制, 就可以做到将正常逻辑和异常逻辑分离. 使代码的可读性更好.
处理异常
try捕捉异常
我们使用 try 语句来捕捉异常(可能触发异常的代码放到try中). 使用except来具体处理异常
如果异常能够被except捕捉到, 则不会影响程序继续执行.
except可以指定一个具体的处理哪种类型异常. 如果try中抛出的异常类型, 不在except中, 那么仍然会程序终止.
如:
IndexError, e相当于捕捉到的这个异常对象的名字为e. 这个异常对象中包含了异常的具体信息.这个e相当于这个异常类的实例
a = [1,2,3]
try:
print(a[100])
print('hello')
except IndexError as e:
print(type(e))
print(e)
#执行结果:
<class 'IndexError'>
list index out of range
#如果把hello放上面:
a = [1,2,3]
try:
print('hello')
print(a[100])
except IndexError as e:
print(type(e))
print(e)
#执行结果:
hello
<class 'IndexError'>
list index out of range
第一个是因为越界产生了异常,所以跳过后序代码,所以不打印hello 直接跳到except部分。
注意:只要有抛出异常,异常之后的代码都不执行,直接终止当前代码块,直接到except
try和except配合
一个try语句, 可以和多个except语句联合工作.
a = [1,2,3]
try:
print(a[100])
except IOError as e:
print(e)
except IndexError as e:
print(e)
#执行结果
list index out of range
try和else配合
一个try语句, 还可以搭配else工作 (else不仅可以和while,for搭配,还可以和try搭配)
a = [1,2,3]
try:
print(a[0])
except IOError as e:
print(e)
except IndexError as e:
print(e)
else:
print("程序没有异常")
#执行结果
1
程序没有异常
except可以不带具体的异常类型, 这样只要try中触发了任意的异常, except都能捕捉到
a = [1,2,3]
try:
print('hello')
print(a[100])
except :
print("捕获到异常")
#执行结果:
hello
捕获到异常
异常的基类:Exception类
Python中内置的异常类, 其实都继承自 Exception 类. 所以上面的代码还可以写成
a = [1,2,3]
try:
print(a[110])
except Exception as e:
print(e)
else:
print("程序没有异常")
#执行结果:
list index out of range
finally
如果想执行一些不管是否触发异常, 都要执行到的代码, 可以放到finally语句块中.finally就是为了做一些善后工作
a = [1,2,3]
try:
print(a[110])
except Exception as e:
print(e)
finally:
print('End')
#执行结果
list index out of range
End
如关闭文件:
with语句的本质就是try…finally
try:
f = open('Z:/test.txt','r')
for line in f:
print(line.strip())
except Exception as e:
print('异常:',' ')
print(e)
finally:
print('End')
f.close() #无论try是否触发异常,都会调用finally中的f.close()
#执行结果
Mango
hello
world
End
抛出异常
raise关键字
使用 raise
关键字在代码中 “抛出异常”
def Divide(x,y):
if y == 0:
raise Exception('divide zero') #除数为0 用异常类创建一个异常对象
return x/y
Divide(1,0)
#执行结果:
Exception: divide zero
因为我们只是抛出了异常, 并没有捕捉异常, 程序还是执行终止了(但是错误信息是我们所定义的异常信息)
略微修改一下程序, 捕捉一下异常
def Divide(x,y):
if y == 0:
raise Exception('divide zero') #除数为0
return x/y
#手动捕获异常
try:
Divide(1,0)
except Exception as e:
print(e)
#执行结果:
divide zero
所谓抛出的 “异常” 其实是一个对象. 我们 Exception(‘divide zero’) 代码实际上是构造了一个异常对
象. 这个对象的类型是Exception(Python异常的基类).
内置异常类
来源:芒果再努力