Python异常处理机制使用准则

异常处理并不复杂. 如果知道代码可能引发某种异常, 且不希望出现这种异常时程序终止并显示栈信息, 可添加必要的语句来处理.

有的时候, 可使用条件语句来达成异常处理实现的目标, 但这样编写出来的代码可能不那么自然, 可读性也没那么高. 另一方面, 有些任务使用if/else完成时看似很自然, 但实际上使用try/except来完成要好得多.

注解

if/else语句将业务代码和错误处理代码混杂在一起, 异常处理机制则实现了将两者分离.

相比使用if/else语句, 异常处理确实会带来性能上的一些影响. 一般而言, 除非程序存在性能方面的问题, 否则不应过多考虑这样的优化. 关键是在很多情况下, 相比于使用if/else, 使用try/except语句更自然, 也更符号Python的风格. 因此, 应养成尽可能使用try/except语句的习惯.

不要过度使用异常

Python异常机制确实方便, 但滥用异常机制也会带来一些负面影响. 过度使用异常主要表现再两个方面:

  • 把异常和普通的错误混淆在一起, 不再编写任何错误处理代码, 而是以简单地引发异常来代替所有的错误处理;

对于完全已知的错误和普通的错误, 应该编写处理这种错误的代码, 增加程序的健壮性. 只有对于外部的, 不能确定和预知的运行时错误才使用异常.

注解

异常处理机制的初衷是将不可预期异常的处理代码和正常的业务逻辑处理代码分离, 因此绝不要使用异常处理来代替正常的业务逻辑判断.

  • 使用异常处理来代替控制流程.

异常处理机制的效率比正常的流程控制效率差, 异常只应该用于处理非正常的情况, 所以不要使用异常处理来代替正常的程序控制流程.

不要使用过于庞大的try语句

如果在try语句中放置大量的代码, 这看上去很”简单”, 但这种”简单”只是一种假象, 只是在编写程序时看上去比较简单. 但因为try语句里的代码过于庞大, 业务过于复杂, 就会造成try语句中出现异常的可能性大大增加, 从而导致分析异常原因的难度也大大增加.

而且在try语句过于庞大时, 就难免在其后跟大量的except子句才可以针对不同的异常提供不同的处理逻辑. 在同一个try语句后紧跟大量的except子句则需要分析它们之间的逻辑关系, 反而增加了编程的复杂度.

正确的做法是, 把大块的try语句分割成多个可能出现异常的程序段落, 并把它们放在单独的try语句中, 从而分别捕获并处理异常.

不要忽略捕获到的异常

不要忽略异常! 既然已经捕获到异常, 那么except子句应该做些有用的事情, 及时处理并修复异常. except子句为空, 或者仅仅打印简单的异常信息都是不妥的.

通常建议对异常采取适当的措施, 比如:

  • 处理异常

对异常进行合适的修复, 然后绕过异常发生的地方继续运行; 或者用别的数据进行计算, 以代替期望的方法返回值; 或者提示用户重新操作…… 总之, 程序应该尽量修复异常, 使程序能恢复运行.

  • 重新引发异常

把在当前运行环境下能做的事情尽量做完, 然后把异常包装成当前层的异常, 重新传递给上层调用者.

  • 在合适的层处理异常

如果当前层不清楚如何处理异常, 就不要在当前层使用except语句来捕获异常, 让上层调用者来负责处理该异常.