python异常小结

1.异常处理

python异常处理伪代码如下:

****异常处理****
try:
    代码块(欲执行可能出错的代码)
except 异常类型 as 异常名:
    代码块(出现上面类型的异常后,会执行的异常处理代码)
except 异常类型 as 异常名:
    代码块(出现上面类型的异常后,会执行的异常处理代码)
......(可以嵌入多个except异常处理语句)
else:
    代码块(try语句没出错时会执行的代码)
finally:
    代码块(最终总会执行的代码)

其中上述伪代码指明了各种确定异常后的处理方式,如果不想指明异常类型,可以直接写成:

except:

如下:

try:
    print(10%0)
except:
    print('哈哈,出现问题了')
else:
    print('没有错误,继续执行')
finally:
    print('xx so handsome!')

2.异常传播

---当在函数中出现异常时,如果在函数中处理了异常,则异常不会再传播

---如果函数中未处理异常,则异常会继续向该异常函数的调用处传播

---如果异常函数调用处处理了异常,则异常不会再传播

---如果调用处未处理异常,异常会一直传递到全局作用域(主模块),如果依旧未处理异常,则程序终止,并抛出异常

---当程序出现异常时,所有的异常信息会专门存储到一个异常对象里

---所以,所谓异常传播,就是将异常对象抛给了调用处

以下定义三个函数,其中fn1是异常函数,fn2会调用fn1,fn3会调用fn2:

def fn1():
    print('xx is so handsome!')  #用来测试函数被执行
    print('10/0')                #产生异常的代码块

def fn2():
    print('xx is best!')         #用来测试函数被执行
    fn1()                        #此处调用fn1异常函数

def fn3():
    fn2()                        #此处调用fn2(异常已传播到fn2)

try:
    fn3()                        #执行主程序块
excpt:
    print('xx find erro!')       #获取到异常时执行的代码
else:
    print('no erro happend!')    #没有异常时会执行的代码

以上代码,因为fn1产生异常且未作出处理,所以异常会传递到调用fn1的fn2函数上,并且在fn2处也未对异常作出处理,所以异常会一直传递到主程序fn3上。

在fn3处,如果执行执行fn3(),不使用try...except语句对异常处理,最终会抛出如下的异常:

但实际上,我们已经在最后作出了异常处理,所以最后会按照我们定义的处理方式对异常处理如下: 

3.异常捕获

异常捕获其实就是通过前面的except语句去实现,其有以下几个特点:

---如果except后面不跟任何内容,则会捕获到所有的异常类型

---如果except后面跟着一个异常类型,则只能捕获到该类型的异常

---except可以重复多次来捕捉不同类型的异常

---exception是所有异常的父类,同样可以捕捉到所有的异常类型

---在异常类型后面跟上 as xx,此时的xx就是异常名,同样也是定义的异常对象

---如果执行的主程序上存在多个错误,程序执行时只会抛出第一个产生的异常类型,等修改完第一个异常后,才会继续依次抛出其它异常

举例如下:

try:
    print(c)                                #c是一个变量,变量未定义,产生第一个异常
    print(10/0)                             #0不能作除数,产生第二个异常
except NameError as e:                      
    print('变量名称错误!', e, type(e))       #捕获第一个异常,并指出异常和异常类型
except ZeroDivisionError as f:
    print('被除数不能为0', f, type(f))       #捕获第二个异常,并指出异常和异常类型
except Exception as g:
    print('未知错误', g, type(g))            #捕获其它所有异常,并指出各个异常和异常类型
else:
    print('程序无措,继续执行!')              #无异常时执行的代码
finally:
    print('xx is best!')                    #最终总会执行的代码                    

 如上,主程序存在两个异常,在直接执行时,会捕获到第一个异常并抛出,并不会捕获到第二个异常,其结果如下:

其中分别返回了:

异常处理标识:名称变量错误

具体异常:name 'c' is not defind

异常类型:<class  'NameError'>(y一个名叫NameError的类)

当我们把第一个异常代码去掉或者修改成print('c')后,继续执行程序,才会抛出捕获到第二个异常: 

 

 4.自定义异常类

---所有异常的父类都是exception,所以只需要创建一个类继承exception即可,如下:

def MyError(Exception):
    pass

 5.抛出异常

---使用raise语句来抛出异常

---raise语句后需要跟一个异常类或者异常对象
如下我们定义一个函数:

def add(a,b):
    if a < 0 or b < 0:                        #如果a和b中有一个负数,就向调用处抛出异常
        raise MyErro('两个参数中不能有负数')    #raise后面跟异常类型或异常实例,此处用我们刚刚自定义的异常类MyError
    r = a + b
    return r

add(-1, 3)    #传入参数并执行add函数

其执行结果如下,因为参数中存在负数,会抛出我们刚刚定义的异常:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值