飞道的博客

不用try也可以优雅的处理异常

417人阅读  评论(0)

Pythonista[1]们都知道使用 try 和 except 来处理可能发生的异常,当异常发生时执行我们预先编写好的代码块。

但是常碰到的情形是这样的:

  • 我们知道这个异常有可能发生

  • 我们不关心这个异常,如果发生了,什么也不用处理,直接忽略就好

如果要处理这种情形的异常,那么不必使用 try-except,Python 内置的 contextlib 库提供了一个函数,叫 suppress,是处理这种异常更优雅的方式,Pythonista 一定要尝试使用。

假如我们要对一系列数字的倒数求和,这些数字可能会出现 0,因此需要处理异常,通常情况下,如果使用 try 和 except 会是这样的:


   
  1. nums = [ 3, 0, 3, 0, 3]
  2. result =  0
  3. for num in nums:
  4.     try:
  5.         result +=  1/num
  6.     except ZeroDivisionError:
  7.         pass
  8. print(result) #  1.0

这里,我们捕捉了 ZeroDivisionError 异常并忽略,最终得到数字的倒数的和为 1.0。

假如我们使用 contextlib 库提供的 suppress,代码就是这样的:


   
  1. from contextlib  import suppress
  2. nums = [ 3, 0, 3, 0, 3]
  3. result =  0
  4. for num in nums:
  5.     with suppress(ZeroDivisionError):
  6.         result +=  1/num
  7. print(result) #  1.0

从形式上看,suppress 的代码行数更少,看来也更优雅,更易于阅读理解。

有人会说了,我使用下面的方法一行就搞定了:

result = sum([1/x for x in nums if x != 0])

这当然是完全正确的,上述只是以这个为例子说明下 suppress 的用法,不过当异常类型增多的时候,上述的方法也有弊端,比如数字除了不能为 0,也不能为字符串的情况, 那么就需要写成这样:


   
  1. nums = [ 3, 0, 3, 0, 3, '3'] #有字符串,也需要忽略
  2. result = sum([ 1/x  for x in nums  if x !=  0 and  type(x) ==  int]) 

当异常的情况不断增多,这种写法就很难看了,而使用 suppress,只需要这样:


   
  1. for num in nums:
  2.     with suppress(ZeroDivisionError, TypeError):
  3.         result +=  1/num

甚至,你想忽略所有的异常,只需要给 suppress 传入异常类的基础类 Exception 即可:


   
  1. for num in nums:
  2.     with suppress(Exception):
  3.         result +=  1/num

需要注意的是,不要这样写


   
  1. result =  0 
  2. nums = [ 3, 0, 3, 0, 3]
  3. with suppress(Exception):
  4.      for num in nums:
  5.         result +=  1/num
  6. print(result) #  0.3333333333333333

如果 suppress 写在了循环体的外面,当发生异常时,后面的循环操作将会被 break,因此这种情况下,结果是 0.333333,原因就是第二个数是 0 引发的异常,这个异常虽然被忽略,但后面的循环也停止了。这一点不是 suppress 特有的,你把 try 放循环外面也是一样的:


   
  1. result =  0 
  2. nums = [ 3, 0, 3, 0, 3]
  3. try:
  4.      for num in nums:
  5.         result +=  1/num
  6. except Exception:
  7.     pass
  8.     
  9. print(result) #  0.3333333333333333

本文介绍一种更加优雅的异常处理方法,就是 Python 标准库 contextlib 的函数 suppress 它更加优雅和容易理解。如果觉得本文对你有所帮助,关注、转发、在看,一条龙走起,我就当你打赏了 66 元了,感谢老铁。

往期 Python 编程技巧文章推荐

参考资料

[1]

Pythonista: 表示「Python支持者」,更表示资深的,对代码质量和品味有要求的开发者,这种执念也就是所谓「Pythonic」

留言区


转载:https://blog.csdn.net/somenzz/article/details/109881923
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场