捕获Python程序运行异常

2019年8月10日 / 21次阅读 / Last Modified 2019年9月18日
语法

一个程序在运行过程中,难免出现异常。比如访问的文件路径不存在;数值计算过程中出现除0的情况,或者达到了Infinity而溢出;申请内存时,操作系统返回了失败......捕获程序运行异常,并有针对性的对异常进行适当的处理,有利于程序运行的稳定和可靠。

异常与bug有相似之处,比如访问一个不存在的文件,对于程序来说,它虽然不能控制此文件是否存在,但是却可以通过捕获这个异常来让程序进行妥善的处理。对程序增加各种异常情况的处理,可以说也是在解决bug。

用try...except...结构来捕获异常

使用try...except...结构,可以使Python程序在运行过程中,如果出现异常,不至于程序崩溃退出。

>>> a = 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> try:
...     a = 1/0
... except:
...     pass
...
>>>

除0,会产生ZeroDivisionError异常,如果代码不放在try里面,程序直接够崩溃退出了。这是try...except...结构的最基本的用途。而我们除了不让程序崩溃退出,还希望能够捕获到具体的异常信息。请继续看下面的代码:

>>> try:
...     a = 1/0
... except BaseException as e:
...     print(repr(e))
...
ZeroDivisionError('division by zero')

except这一行的写法有些固定,BaseException是Python中所有的异常类型的基类,所有异常类型,包括自定义的类型,都要从这个类派生。在except分支中个,打印异常信息,注意这里使用的是repr()函数(repr()函数和str()函数的异同)。

如何区别对待不同的异常

在except中使用BaseException,可以捕获所有的异常。不过,很多时候,我们希望能够针对不同的异常,实现不同的处理。请看下面的测试代码:

>>> def test_exception(num):
...     try:
...         a = 1/num
...         if num == 1:
...             import os
...             os.remove('not existed file')
...     except ZeroDivisionError as e:
...         print('1---',repr(e))
...     except FileNotFoundError as e:
...         print('2---',repr(e))
...     except:
...         print('unknown exception')
...
>>> test_exception(0)
1--- ZeroDivisionError('division by zero')
>>> test_exception(1)
2--- FileNotFoundError(2, 'No such file or directory')
>>> test_exception(3)

在except语句后面跟不同的异常类型,就可以对异常进行区别处理。try...except...语句结构,一个try后面可以跟很多个except,每个except都可以对应某个不同的异常处理分支。其实,一个except还可以同时包含多个异常,即相当于我们对某几个不同的异常,采用同样的处理:

>>> import os
>>> def test_exception2(num):
...     try:
...         a = 1/num
...         if num == 1: os.remove('NotExistedFile')
...     except (ZeroDivisionError, FileNotFoundError) as e:
...         print('3---', repr(e))
...
>>> test_exception2(0)
3--- ZeroDivisionError('division by zero')
>>> test_exception2(1)
3--- FileNotFoundError(2, 'No such file or directory')

except后面跟着的多个异常类型,要把它们写成tuple的形式。

except后面的as

本文上面的测试代码,except语句后面基本都有as e,as的作用是将异常对象赋值给变量e,这样在except结构中,就可以直接通过repr(e)来获取异常的信息。

也可以不写as,如果你的代码不需要访问异常对象的话。比如下面这样:

>>> try:
...     a = float('abcde')
... except:
...     print('excepton occur')
...
excepton occur
>>> try:
...     a = float('abcde')
... except ValueError:
...     print('value error')
...
value error

这些写法都OK,只是异常处理代码就拿不到异常对象了,一般不建议这样写。

代码中有了异常捕获和处理,Python程序就会显得更加健壮。

-- EOF --

本文链接:https://www.pynote.net/archives/823

留言区

《捕获Python程序运行异常》有3条留言

电子邮件地址不会被公开。 必填项已用*标注

  • 麦新杰

    单独使用raise语句,抛出上下文相关的异常。还可以设计不同异常在哪个层次处理,非常灵活,代码结构也很优雅。 [回复]

  • 麦新杰

    非GUI程序,默认在有异常时,会导致python解释器退出,效果相当于程序运行停止。而如果是GUI程序,比如某个Button对应的函数里面发生异常,GUI程序不会退出,如果你运行的是.pyw,这时没有console窗口,就无法发现异常。 [回复]

  • 麦新杰

    BaseException    所有异常的基类
    Exception    常规错误的基类
     [回复]


前一篇:
后一篇:

More

麦新杰的Python笔记

Ctrl+D 收藏本页


©Copyright 麦新杰 Since 2019 Python笔记

go to top