无论你是多么优秀的程序员,你都不能保证自己的程序永远不会出错。就算你的程序没有错,用户也不一定按照你设定的规则来使用你的程序,总有一些小白或者极客会“玩弄”你的程序。
除此以外,你也不能保证程序的运行环境永远稳定,比如操作系统可能崩溃,网络可能无法连接,内存可能突然坏掉……
总之,你基本什么都保证不了。但是,作为一个负责任的程序员,我们要让自己的程序尽可能的健壮,尽可能保证在恶劣环境下还能正常运行,或者给用户提示错误,让用户决定是否退出。
例如有一个五子棋程序,当用户输入落子的坐标时,程序既要判断输入格式是否正确(横坐标和纵坐标之间由逗号分隔),还要判断坐标是否在合法的范围内。一般我们都会这样来处理:
if 坐标包含了除逗号之外的其它非数字字符:
alert 坐标只能是数值
goto retry
elif 坐标不包含逗号:
alert 必须使用逗号分隔横坐标和纵坐标
goto retry
elif 坐标落在了棋盘外:
alert 坐标必须位于棋盘之内
goto retry
elif 作为位置已有其它棋子:
alert 只能在没有棋子的位置落子
goto retry
else:
#正常的业务代码
……
上面的代码并没有涉及所有出错情形,只是考虑了四种可能出错的情形,代码量就已经急剧增加了。
在实际开发中,不可预料的情况呈数量级增长,甚至不能穷举,按照上面的逻辑来处理各种错误简直让人抓狂。
如果每次在实现真正的业务逻辑之前,都需要不厌其烦地考虑各种可能出错的情况,针对各种错误情况给出补救措施,这是多么乏味的事情啊。程序员喜欢解决问题,喜欢开发带来的“创造”快感,但不喜欢像一个“堵漏”工人,去堵那些由外在条件造成的“漏洞”。
对于构造大型、健壮、可维护的应用而言,错误处理是整个应用需要考虑的重要方面,程序员不能仅仅只做“对”的事情,程序员开发程序的过程,是一个创造的过程,这个过程需要有全面的考虑,仅做“对”的事情是远远不够的。
对于上面的错误处理机制,主要有如下两个缺点:
- 无法穷举所有的异常情况。因为人类知识的限制,异常情况总比可以考虑到的情况多,总有“漏网之鱼”的异常情况,所以程序总是不够健壮。
- 错误处理代码和业务实现代码混杂。这种错误处理和业务实现混杂的代码严重影响程序的可读性,会增加程序维护的难度。
程序员希望有一种强大的机制来解决上面的问题,能够将上面程序改成如下的形式:
if 用户输入不合法:
alert 输入不合法
goto retry
else :
#正常的业务代码
……
上面伪码提供了一个非常强大的“if 块”,即程序不管输入错误的原因是什么,只要用户输入不满足要求,程序就一次处理所有的错误。这种处理方法的好处是,使得错误处理代码变得更有条理,只需在一个地方处理错误。
现在的问题是,“用户输入不合法”这个条件怎么定义?当然,对于这个简单的要求,可以使用正则表达式对用户输入进行匹配,当用户输入与正则表达式不匹配时即可判断“用户输入不合法”。但对于更复杂的情形,就没有这么简单了。使用 Python 的异常处理机制就可以解决这个问题,例如:
try:
if(用户输入不合理):
raise 异常
except Exception:
alert 输入不合法
goto retry
#正常的业务代码
此程序中,通过在 try 块中判断用户的输入数据是否合理,如果不合理,程序受 raise 的影响会进行到 except 代码块,对用户的错误输出进行处理,然后会继续执行正常的业务代码;反之,如果用户输入合理,那么程序将直接执行正常的业务代码。
try except 是 Python 实现异常处理机制的核心结构,其具体用法会在后续章节做详细介绍。
显然,使用 Python 异常处理机制,可以让程序中的异常处理代码和正常业务代码分离,使得程序代码更加优雅,并可以提高程序的健壮性。
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/21381.html