打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
关于Python异常处理的一些建议


来源:强哥  公众号:Python与数据分析   链接:

https://mp.weixin.qq.com/s/PU0-TwTABa1eC3BzxAzcbw


Python中的异常处理一般是如下的形式:

try:
   
except : # try中发生name1的异常时处理
   
except , : # try中发生name2, name3的异常时处理
   
except: # 其他异常发生时处理
   
else: # 没有异常发生时执行
   
finally: # 不管有没有异常发生都实行
   


在写异常处理的时候通常有以下两点建议

  • 尽量定位具体的异常类型,不要使用单独的except处理所有异常

  • 注意异常捕获的顺序


对于上面两点,下面分别举例说明。


尽量定位具体的异常类型,不要使用单独的except处理所有异常

这里我们定义一个Person的类,并实现两个方法,一个是 set_age 用于设置年龄,一个是 set_weight 用于设置体重。当设置年龄或者体重为负值是,程序抛出异常。代码如下

import sys

class InvalidAge(Exception):
   pass
class InvalidWeight(Exception):
   pass

class Person(object):
   def __init__(self):
       pass

   def set_age(self, age):
       if age <>0:
           raise InvalidAge()
       self.age = age

   def set_weight(self, weight):
       if weight <=>0:
           raise InvalidWeight()
       self.weight = weight

我们来看下下面的异常处理的代码

p = Person()
try:
   p.set_age(30)
   p.set_weight(-30)
except:
   sys.exit('Age cannot be negative')

这段代码会输出

Age cannot be negative


这个输出会让我们以为是年龄设置出了问题,但实际上年龄的设置并没有问题,而是体重的设置出了问题。由于单独使用except语句,真实的错误被掩盖。

如果我们在用except捕获异常的时候使用更精确的异常类型定位,就可以避免这样的问题。如下

try:
   p.set_age(30)
   p.set_weight(-30)
except InvalidAge:
   sys.exit('Age cannot be negative')
except InvalidWeight:
   sys.exit('Weight cannot be negative')

输出:

Weight cannot be negative

使用单独的except会捕获所有的异常,给debug增加难度。如果在某些情况下不得不这样用,建议用raise向上层抛出异常。


注意异常捕获的顺序

Python的内建异常有一定的继承结构,如ZeroDivisionError继承自ArithmeticError,ArithmeticError继承自StandardError,StandardError继承自Exception,Exception继承自BaseException。

一般在捕获异常的时候建议先捕获子类的异常,后捕获父类的异常。这样,在有异常发生时,python解释器会根据except声明的顺序进行匹配,在第一个匹配的地方就立即处理异常。

我们修改一下前面的例子。定义一个异常类的基类InvalidValue,并且两个异常类InvalidAge和InvalidWeight都继承自InvalidValue类。如下

class InvalidValue(Exception):
   pass
class InvalidAge(InvalidValue):
   pass
class InvalidWeight(InvalidValue):
   pass

修改异常处理部分的代码如下

p = Person()
try:
   p.set_age(30)
   p.set_weight(-30)
except InvalidValue:
   sys.exit('Invalid value')
except InvalidAge:
   sys.exit('Age cannot be negative')
except InvalidWeight:
   sys.exit('Weight cannot be negative')

上面的例子会输出

Invalid value

这里InvalidWeight类继承自InvalidValue类,当抛出InvalidWeight异常的时候,由于它是InvalidValue的子类,在except InvalidValue处就被捕获了,输出了Invalid value的消息,而真正处理InvalidWeight异常的消息却被掩盖了。

改变一下异常捕获的顺序,把捕获子类的except语句放在捕获父类的except语句之前,就可以避免这样的问题。如下

p = Person()
try:
   p.set_age(30)
   p.set_weight(-30)
except InvalidAge:
   sys.exit('Age cannot be negative')
except InvalidWeight:
   sys.exit('Weight cannot be negative')
except InvalidValue:
   sys.exit('Invalid value')

输出

Weight cannot be negative

可以看到,在写异常处理的时候注意以上两点,可以帮助我们更准确的定位异常类型,提高debug的效率。


(完)


看完本文有收获?请转发分享给更多人

关注「Python那些事」,做全栈开发工程师

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Python网络编程Socket应用实例
exit、quit、sys.exit、os._exit,这么多退出方式,它们之间有什么区别呢?
python 文档对比,python实现比较文件内容异同
DataSnap与JSON序列化(3)
判断异常类型,全面捕获Python的异常
python异常如何全面捕获
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服