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

Python七号

共 2022字,需浏览 5分钟

 ·

2020-11-22 18:09

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

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

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

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

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

nums = [3,0,3,0,3]
result = 0
for num in nums:
    try:
        result += 1/num
    except ZeroDivisionError:
        pass
print(result) # 1.0

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

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

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

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

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

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

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

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

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

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

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

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

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

result = 0 
nums = [3,0,3,0,3]
with suppress(Exception):
    for num in nums:
        result += 1/num

print(result) # 0.3333333333333333

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

result = 0 
nums = [3,0,3,0,3]
try:
    for num in nums:
        result += 1/num
except Exception:
    pass
    
print(result) # 0.3333333333333333

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

往期 Python 编程技巧文章推荐

参考资料

[1]

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


留言区

浏览 38
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报