Python异常处理机制到底有什么用?

异常处理是现代编程语言不可或缺的能力,它已经成为衡量一门编程语言是否成熟和健壮的标准之一C++、Java、C#、Python 等高级语言都提供了异常处理机制。

无论你是多么优秀的程序员,你都不能保证自己的程序永远不会出错。就算你的程序没有错,用户也不一定按照你设定的规则来使用你的程序,总有一些小白或者极客会“玩弄”你的程序。

除此以外,你也不能保证程序的运行环境永远稳定,比如操作系统可能崩溃,网络可能无法连接,内存可能突然坏掉……

总之,你基本什么都保证不了。但是,作为一个负责任的程序员,我们要让自己的程序尽可能的健壮,尽可能保证在恶劣环境下还能正常运行,或者给用户提示错误,让用户决定是否退出。

例如有一个五子棋程序,当用户输入落子的坐标时,程序既要判断输入格式是否正确(横坐标和纵坐标之间由逗号分隔),还要判断坐标是否在合法的范围内。一般我们都会这样来处理:

if 坐标包含了除逗号之外的其它非数字字符:
    alert 坐标只能是数值
    goto retry
elif 坐标不包含逗号:
    alert 必须使用逗号分隔横坐标和纵坐标
    goto retry
elif 坐标落在了棋盘外:
    alert 坐标必须位于棋盘之内
    goto retry
elif 作为位置已有其它棋子:
    alert 只能在没有棋子的位置落子
    goto retry
else:
    #正常的业务代码
    ......

上面的代码并没有涉及所有出错情形,只是考虑了四种可能出错的情形,代码量就已经急剧增加了。

在实际开发中,不可预料的情况呈数量级增长,甚至不能穷举,按照上面的逻辑来处理各种错误简直让人抓狂。

如果每次在实现真正的业务逻辑之前,都需要不厌其烦地考虑各种可能出错的情况,针对各种错误情况给出补救措施,这是多么乏味的事情啊。程序员喜欢解决问题,喜欢开发带来的“创造”快感,但不喜欢像一个“堵漏”工人,去堵那些由外在条件造成的“漏洞”。

对于构造大型、健壮、可维护的应用而言,错误处理是整个应用需要考虑的重要方面,程序员不能仅仅只做“对”的事情,程序员开发程序的过程,是一个创造的过程,这个过程需要有全面的考虑,仅做“对”的事情是远远不够的。

对于上面的错误处理机制,主要有如下两个缺点:

1、无法穷举所有的异常情况。因为人类知识的限制,异常情况总比可以考虑到的情况多,总有“漏网之鱼”的异常情况,所以程序总是不够健壮。

2、错误处理代码和业务实现代码混杂。这种错误处理和业务实现混杂的代码严重影响程序的可读性,会增加程序维护的难度。


程序员希望有一种强大的机制来解决上面的问题,能够将上面程序改成如下的形式:

if 用户输入不合法:
    alert 输入不合法
    goto retry
else :
    #正常的业务代码
    ......

上面伪码提供了一个非常强大的“if 块”,即程序不管输入错误的原因是什么,只要用户输入不满足要求,程序就一次处理所有的错误。这种处理方法的好处是,使得错误处理代码变得更有条理,只需在一个地方处理错误。

现在的问题是,“用户输入不合法”这个条件怎么定义?当然,对于这个简单的要求,可以使用正则表达式对用户输入进行匹配,当用户输入与正则表达式不匹配时即可判断“用户输入不合法”。但对于更复杂的情形,就没有这么简单了。使用 Python 的异常处理机制就可以解决这个问题,例如:

try:
    if(用户输入不合理):
        raise 异常
except Exception:
    alert 输入不合法
    goto retry
#正常的业务代码

此程序中,通过在 try 块中判断用户的输入数据是否合理,如果不合理,程序受 raise 的影响会进行到 except 代码块,对用户的错误输出进行处理,然后会继续执行正常的业务代码;反之,如果用户输入合理,那么程序将直接执行正常的业务代码。

try except 是 Python 实现异常处理机制的核心结构,其具体用法会在后续章节做详细介绍。

显然,使用 Python 异常处理机制,可以让程序中的异常处理代码和正常业务代码分离,使得程序代码更加优雅,并可以提高程序的健壮性。