捕获异常

一旦发生异常,程序就会终止,这是非常糟糕的事情,这种糟糕体现在两方面

  1. 即便发生了异常,业务上可以忽略它,那么程序应当继续执行
  2. 程序终止,使得异常的信息没有被保留下来,不利于问题的分析和总结

为了提高程序的健壮性和解决问题,可以将异常捕获,根据业务要求来做对应的处理

1. try

python中,捕获异常使用try ... except ...这种语法来捕捉异常,下面是一个异常捕获的示例

def test(a, b):
    try:
        print(a/b)
    except ZeroDivisionError:
        print("0不能作分母")

if __name__ == '__main__':
    test(10, 5)
    test(10, 0)

那些你担心不安全的代码,就可以放在try子句中,也就是try和except之间。

2. except

except 可以指定想要捕获的异常,比如上面的例子中,代码想捕获ZeroDivisionError 异常,如果try子句中发生了别的异常,这个except 就不会捕捉。

这样做,是希望能够针对不同的异常做不同的处理,你可以一次性指定想要捕获的所有异常,比如下面的代码

def test(a, b):
    try:
        print(a/b)
    except (ZeroDivisionError, ValueError):
        return None

if __name__ == '__main__':
    test(10, 5)
    test(10, 0)

也可以逐个捕捉

def test(a, b):
    try:
        print(a/b)
    except ZeroDivisionError:
        print('0不能做分母')
    except ValueError:
        print("类型错误")
    else:
        print('什么异常都没发生')

if __name__ == '__main__':
    test(10, 5)
    test(10, 0)

try ... except ... else这种语法,当没有异常发生时,就会执行else语句块里的代码。

如果你对于异常还不熟悉,不知道该捕获哪些异常,则可以用下面的写法

def test(a, b):
    try:
        print(a/b)
    except:
        print('发生异常')

if __name__ == '__main__':
    test(10, 5)
    test(10, 0)

如果你什么异常都不指定,那么任何异常都会被捕捉,但这不是一个好的写法,因为这意味着,你根本不了解你的程序,因为不了解,你连可能发生的异常是什么都不清楚,这是很致命的,你不了解你自己写出来的程序,还怎么指望它能正常工作?

3. finally

你可以在finally语句块里做清理操作,因为不论try子句里是否发生异常,也不论你在except语句块里做了什么操作,总之,最终一定会执行finally语句块里的代码,这就保证了这里的代码最后一定会被执行,所以,清理收尾的工作一定会进行。

你可以在这里输出日志,你可以做任何你想做的事情。

def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("division by zero!")
    else:
        print("result is", result)
    finally:
        print("executing finally clause")

if __name__ == '__main__':
    divide(10, 5)
    divide(10, 0)

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案