内容简介:LBYL 的意思是“Look before you leap.” 指在程序执行之前做好检查。比如下面这段代码:EAFP 的意思是“Easier to ask for forgiveness than permission.” 在编程方面指的是相信程序会正确执行,如果出错了再处理错误,比如上面这段代码用 EAFP 风格写就是下面这样:很多情况下,两种方式的写法是可以互相替换的,但是
LBYL 的意思是“Look before you leap.” 指在程序执行之前做好检查。比如下面这段代码:
if "key" in my_dict: x = my_dict["key"] else: # handle missing key
EAFP 的意思是“Easier to ask for forgiveness than permission.” 在编程方面指的是相信程序会正确执行,如果出错了再处理错误,比如上面这段代码用 EAFP 风格写就是下面这样:
try: x = my_dict["key"] except KeyError: # handle missing key
很多情况下,两种方式的写法是可以互相替换的,但是 Python 鼓励 EAFP 。原因是这种方法的可读性更高,速度也更快(只有在出错的时候才需要处理,而 LBYL 需要每次运行都检查)。
现在的大多数语言都有异常处理机制了,比如 Java, Python, Ruby 等,没有异常处理机制的都是一些古老的语言,比如 C 语言。但是没有异常处理机制并不代表程序总能运行正确,所以 C 语言需要其他形式来处理程序(函数)不能正确运行的情况,一般的方法是返回 0
表示运行正常,其他值表示运行异常。
但是这种处理形式有两个缺点(这部分可以参考《代码之髓》这本书的第 6 章):第一是可能遗漏错误。比如一个函数在大部分情况下都能正确运行,只有在很少的情况下会出错,或者只有改变了环境之后才会出错。那么很可能 程序员 会默认这个函数总是正确的,而忘记处理这个异常。如果是 Java 的话,程序员就必须在调用函数的地方处理掉所有可能的异常(虽然很多 Java 程序员喜欢不优雅地用 RuntimeError 处理所有的异常)。更让人头疼的事情是,一旦这“极少数”的情况发生了,那么错误经常不在错误出现的地方,而在很外层的一个调用处。你要花很多时间调试才能找到最终出错的地方。如果有异常处理机制的话,异常栈通常会直接给出 Exception 发生的地方。
第二个缺点是会使代码的可读性下降。因为要检查函数的返回值,要写很多 if-else
,程序真正的逻辑就变得难以阅读。我记得有位高人说过这么一句话,具体是谁说的记不得了,大意是:“高级语言和低级语言的区别是,需要不需要写很多与程序的逻辑无关的东西。” 很多 if-else
,很难看出这个只是判断,还是程序逻辑/业务的判断。如果用 try-catch
,那么 try
代码块里面可以只写程序的逻辑,在 except
里面处理所有的异常。
即使在有异常处理机制的语言中,比如 Python,很多人喜欢做的一个事情是在子函数用 if 判断,然后 logger.error + return。其实不如 raise ,然后在调用者那里 try-catch,更能表达逻辑。
if not monitor_config.link:
logger.error(f'{self} does not associate with link')
return
此外,Python 语言内置的协议也大量使用了异常的机制。比如《fluent python》(314页)关于重载加运算符 __add__
就提到,为了遵守鸭子精神,不要测试 other 操作数的类型,而是应该捕获异常,然后抛出 NotImplemented
。
这样的好处是,比如我们定义了一个新的数据类型,支持和 int
相加 a.__add__(4)
。但是内置的 int
可不支持和我们自定义的类型相加, 4.__add__(a)
就会抛出异常。这时解释器尝试用 __radd__
来处理(即 a.__add__(4)
)。如果 int
的 __add__
是实现是相加对象的类型,如果不符合预期就抛出一个 TypeError
,就没有这样的便利了。
但是 EAFP 在某些情况下可能是不可行的,它的一个问题就是等错误发生的时候,程序已经运行了一半,如果函数会造成一些副作用,那么这个时候副作用已经发生了。这种情况下,如果没有数据事务这种外部的东西来提供原子性的话,就比较麻烦了,需要手动清理副作用的状态。而 LBFY 这种风格可以尽量保证提供给程序的参数正确,可以顺利运行完成。
其实我想讨论这二者的区别的真正地方是,在生活中也会有这两种风格的处理方式。
团队管理上 try-catch 更自由,更人性化,大家可以关注自己“做事的逻辑”而没有很多条条框框,在程序上 if 可能就多了一次判断,但是在实际生活中的话,这种 if 可能是各种各样的沟通和 ask permission,效率可就不只低这么多了。但是换句话来说,严谨的系统容不得做到半路才出现 “Exception”,还是需要“Look before you leap”的。
参考资料:
- https://www.codeproject.com/Tips/490765/If-else-instead-of-try-catch
- https://www.quora.com/When-should-I-use-try-catch-instead-of-if-else
- https://en.wikiquote.org/wiki/Grace_Hopper
- https://stackoverflow.com/questions/12265451/ask-forgiveness-not-permission-explain
- https://stackoverflow.com/questions/11360858/what-is-the-eafp-principle-in-python
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ordering Disorder
Khoi Vinh / New Riders Press / 2010-12-03 / USD 29.99
The grid has long been an invaluable tool for creating order out of chaos for designers of all kinds—from city planners to architects to typesetters and graphic artists. In recent years, web designers......一起来看看 《Ordering Disorder》 这本书的介绍吧!