Python的异常概念介绍以及处理
一、什么是异常处理
定义:异常处理就是我们在写Python时,经常看到的报错信息,例如;NameErrorTypeErrorValueError等,这些都是异常。
异常是一个事件,改事件会在程序执行过程中发生,影响程序的正常执行,一般情况下,在python中无法处理程序时就会发生异常,异常时Python的一个对象,表示一个错误,当Python脚本发生异常时,我们需要捕获并处理异常,否则程序就会终止执行。
二、异常处理
当Python脚本出现异常的时候我们怎么处理那?
就如我们使用的工具出现了一点毛病,我们可以想办法修理好它,程序也是一样,之前的前辈们经过不断的积累与思考,创造了很多好得方法处理程序中出现的异常,本章我们就讲一下使用try语句处理异常。
首先我们来说一下try语句的语法:
try语句与except相结合使用,此语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理,如果不想在发生异常时结束程序,只需要在try语句中捕获异常即可
try: <代码块> except<异常名字> print(‘语句') 实例如下: deffunc(): try: a=x/y print('a=',a) returna ecceptException: print('程序出现异常,异常信息:被除数为0')
三、抛出异常
在Python中使用raise语句抛出一个指定的异常,我们可以使用类或实例参数调用raise语句引发异常。
实例如下:
classEvaException(BaseException): def__init__(self,msg): self.msg=msg def__str__(self): returnself.msg try: raiseEvaException('类型错误') exceptEvaExceptionase: print(e)
四、捕捉多个异常
我们前面说了怎么处理一个异常的情况,如果涉及到多个,我们该怎么处理那?
在Python中支持一个try/except语句处理多个异常,语法如下:
try: <语句> except<异常名字>: print(‘异常说明') except<异常名字>: print(‘异常说明') try语句的工作方式如下: 首次执行try中语句块,如果没有发生异常,则忽略except中的字句,try语句中的代码块执行后结束。如果try语句中的代码块出现异常,try中的剩余语句则会被忽略, 如果异常和eccept中的异常名字一直,相应的except语句就会被执行。如果一个异常也没有匹配,这个异常就会传递给上层的try语句中,一个语句可能包含第一个except语句, 分别处理不同的异常,但是最多只有一个分支会执行。 try: #a #1/0 dic={1:2} dic[3] exceptNameError: print('名字没有定义,报错了') exceptZeroDivisionError: print('0不能当做除数,报错了') exceptKeyError: print('没有这个key')
五、异常中else
我们如果程序执行完异常后还想做其他的事情怎么办?
这时我们就可以用到异常中的else了,具体语法如下:
try: <语句> except<异常名字>: <语句> except<异常名字>: <语句> else: <语句>#(try语句中没有异常后执行此段代码) 如果在try语句中执行没有发生异常,就会执行else语句,使用else语句比把所有语句都放在try字句里面更好,这样可以避免一些意想不到的而except有没有捕获到的异常: deffunc(x,y): try: a=x/y except: print('Error,happened') else: print('Itwentasexecpt') func(2,1)
六、用户自定义异常
你可以通过创建一个新的exception类来拥有自己的异常。异常应该继承自Exception类,或者直接继承,或者间接继承,例如:
classMyError(Exception): def__init__(self,value): self.value=value def__str__(self): returnrepr(self.value) try: raiseMyError(2*2) exceptMyErrorase: print('Myexceptionoccurred,value:',e.value) Myexceptionoccurred,value:4 raiseMyError('oops!') Traceback(mostrecentcalllast): File"",line1,in? main__.MyError:'oops!' 在这个例子中,类Exception默认的__init__()被覆盖。 当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类: classError(Exception): """Baseclassforexceptionsinthismodule.""" pass classInputError(Error): """Exceptionraisedforerrorsintheinput. Attributes: expression--inputexpressioninwhichtheerroroccurred message--explanationoftheerror """ def__init__(self,expression,message): self.expression=expression self.message=message classTransitionError(Error): """Raisedwhenanoperationattemptsastatetransitionthat'snot allowed. Attributes: previous--stateatbeginningoftransition next--attemptednewstate message--explanationofwhythespecifictransitionisnotallowed """ def__init__(self,previous,next,message): self.previous=previous self.next=next self.message=message 大多数的异常的名字都以"Error"结尾,就跟标准的异常命名一样。
七、定义清理行为(finally语句)
try语句还有另外一个可选的子句,它定义了无论在任何情况下都会执行的清理行为。例如:
>>>try: ...raiseKeyboardInterrupt ...finally: ...print('Goodbye,world!') ... Goodbye,world! Traceback(mostrecentcalllast): File"",line2,in KeyboardInterrupt 以上例子不管try子句里面有没有发生异常,finally子句都会执行。 如果一个异常在try子句里(或者在except和else子句里)被抛出,而又没有任何的except把它截住,那么这个异常会在finally子句执行后再次被抛出。 下面是一个更加复杂的例子(在同一个try语句里包含except和finally子句): >>>defdivide(x,y): try: result=x/y exceptZeroDivisionError: print("divisionbyzero!") else: print("resultis",result) finally: print("executingfinallyclause") >>>divide(2,1) resultis2.0 executingfinallyclause >>>divide(2,0) divisionbyzero! executingfinallyclause >>>divide("2","1") executingfinallyclause Traceback(mostrecentcalllast): File" ",line1,in? File" ",line3,individe TypeError:unsupportedoperandtype(s)for/:'str'and'str' 预定义的清理行为 一些对象定义了标准的清理行为,无论系统是否成功的使用了它,一旦不需要它了,那么这个标准的清理行为就会执行。 这面这个例子展示了尝试打开一个文件,然后把内容打印到屏幕上: forlineinopen("myfile.txt"): print(line,end="") 以上这段代码的问题是,当执行完毕后,文件会保持打开状态,并没有被关闭。 关键词with语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行他的清理方法: withopen("myfile.txt")asf: forlineinf: print(line,end="") 以上这段代码执行完毕后,就算在处理过程中出问题了,文件f总是会关闭。
python标准异常