在编写程序的时候,通常会出现一些异常情况。虽然此时也可以用if语句实现对异常语句的检查,但是这样的代码可读性比较差,此时就需要采用异常处理的机制来编写代码。Python中提供了一些异常类(Python中用异常对象来表示异常情况),同时也可以自己定义自己的异常。如果异常对象未被处理或者捕捉,程序就会用所谓的回溯(Traceback)终止执行。
异常和函数一起使用,如果异常在函数内引发而不处理,它就会传播至函数调用的地方。如果调用的地方也没有处理异常,则异常继续向上传播,一直到达主程序,如果此时还是没有处理异常,程序就会带着堆栈跟踪终止。
(1)Python中提供的异常类
Exception:所有异常类的基类
AttributeError:特性或者赋值失败时引发
IOError:试图打开不存在文件时引发
IndexError:使用序列中不存在的索引时引发
KeyError:使用映射中不存在的键时引发
NameError:找不到变量名字时引发
SyntaxError:语法错误时引发
TypeError:内建操作或者函数应用错误类型的对象时引发
ValueError:内建操作或者函数应用于正确类型的对象,但是该对象使用不适合的值时引发
ZeroDivisionError:在除法或者模除操作第二个操作数为0时引发
尽管内建的异常类包含了大部分的情况,但是有时候还是需要创建自己的异常类,只要确保从Exception类继承(不管是直接的还是间接的)
class MyException(Exception):pass
(2)如何引发异常
为了引发异常,可以使用一个Exception的子类或者实例参数调用raise语句。
>>> raise Exception("I am an Exceprion") #可以带参数
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
raise Exception("I am an Exceprion")
Exception: I am an Exceprion
(3)如何捕捉异常
使用try/except来实现。再也不是try/catch了哈。下面用到了try/except语句中的else语句,也就是说没有捕捉到异常就会执行else语句块。
while True:
try:
x = int(input('please input x:'))
y = int(input('please input y:'))
print (x/y)
except ZeroDivisionError: #捕捉到异常就会继续输入
print ('The second num can not be 0')
else: #如果输入正确的数就会停止输入
break
一个try/except可以通过元组捕捉多个异常
while True:
try:
x = int(input('please input x:'))
y = int(input('please input y:'))
print (x/y)
except (ZeroDivisionError,TypeError):
print ('Input Invalid')
else:
break
同时,使用空的except句子可以捕捉所有Exception类的异常。
while True:
try:
x = int(input('please input x:'))
y = int(input('please input y:'))
print (x/y)
except Exception:
#except: 这种空语句也能捕捉全部异常
print ('Input Invalid')
else:
break
(4)finally语句
finally肯定会被执行,不管try语句是否引发异常。负责一些清理的工作
x = None
try:
1/0
finally:
print ('Cleaning Up...')
del x
(5)屏蔽异常
只要处理异常,就表示该异常被处理了
class MuffleException:
muffled = False
def cal(self,exp):
try:
return eval(exp)
except ZeroDivisionError:
if self.muffled:#处理异常
print('Division by Zero')
else:
raise #异常继续
obj = MuffleException()
obj.muffled = True
obj.cal('2/0')
>>>Division by Zero