防御式编程 EAFP 和 LBYL 的一些思考

这个主题的思考来源于工作时涉及到的资源回收场景。为了增强程序的健壮性,通常会增加一些检查数据项的代码的防御性编程。关于事先检查和异常处理, 这是个很多人都在讨论的问题,Python 中有两个术语来分别表示:

  • LBYLLook Before You Leap, 操作前先检查,再执行
  • EAFPEasier to Ask Forgiveness than Permission, 操作前不检查,出了问题由异常处理来处理

比如从字典中取出 key 所对应的 value 并进行操作时

1
2
3
4
5
6
# LBYL
if "key" in test_dict:
x = test_dict["key"]
else:
# key 不存在

1
2
3
4
5
# EAFP
try:
x = test_dict["key"]
except KeyError:
# key 不存在

这两种哪种更好呢 ?

  • 在代码效率上, LBYL 则会消耗更高的固定成本,因为无论成败与否,总是执行额外的检查
  • 在代码逻辑性上,我个人会更倾向于 LBYL,毕竟传入的数据是否合理,类型是否正确,资源是否存在是一个事情的前提,先检查再执行很合理
  • 在代码可读性上,因为上面这点,LBYL 会把代码逻辑上隔离开,导致在可读性上会稍微逊色一点。
  • 在潜在风险上,在高并发场景下,if 条件如果是个表达式,可能会造成一致性问题,这个更推荐用 EAFP 形式。

Reference & Recommendation:

关于头图

拍摄自迪拜

Python SocketServer 源码阅读
urlparse 源码阅读