Py学习  »  Python

听说你会玩 Python 系列 4 - LBYL vs EAFP

王的机器 • 3 年前 • 392 次点击  




本文含 2019 2 图表截屏
建议阅读 6 分钟


本文是听说你会玩 Python 系列的第四篇





引言


写了 Python 这么久,是不是对 LBYL 和 EAFP 这两个缩写还一无所知?先看一下它们的全称:


  • LBYL Look Before Your Leap:三思后行

  • EAFP Easier to Ask Forgiveness than Permission:先斩后奏


它们其实是两种编程风格。


  • 前者是谨慎,在程序执行之前做好检查,代码不 pythonic。

  • 后者是飘逸,相信程序大概率对的,错了再处理,代码很 pythonic。


还是不知道在说什么?看例子吧。






两个例子


列表例子
l = [1, 2, 3]


当打印列表中某个索引对应的元素时,我们想确保这个索引没有超出范围。以上面一个含有三个元素的列表为例:



LBYL 写法


if len(l) >= 3:    print(l[2])else:    print('该索引不存在!')
3


如果实现检查该列表 l 长度大于等于 3, 我们是可以打印出索引为 2 对应的元素的。


如果 l = [1, 2] 了呢?

l = [1, 2]
if len(l) >= 3: print(l[2])else: print('该索引不存在!')
该索引不存在!


虽然达到了目的,我相信你已经觉得上面代码不好看了吧,而且 if 语句中 len(l) >= 3 里的 3 还需要 hard-code。




EARP 写法


l = [1, 2, 3]
try:    print(l[2])except IndexError:    print('该索引不存在!')
3


用 try-block 语句。打印列表中的元素大多情况都不会报错,报错的话应该就是索引超出范围,再处理 IndexError 就完事了。


l = [1, 2]
try:    print(l[2])except IndexError:    print('该索引不存在!')
该索引不存在!



字典例子
stock = {'name':'腾讯', 'price':435, 'curr':'港币'}


当从字典中用键获取值时,我们想确保这个键是存在于字典里。




LBYL 写法


在 if 语句中检查每个键是否在字典 stock 中。

if 'name' in stock and 'price' in stock and 'curr' in stock:    print( f"{stock['name']}股票价格 {stock['price']} {stock['curr']}." )else:    print('某些键不存在!')
腾讯股票价格 435 港币.


如果现在字典里没有 'curr' 这个键呢?


stock = {'name':'腾讯', 'price':435}
if 'name' in stock and 'price' in stock and 'curr' in stock:    print( f"{stock['name']}股票价格 {stock['price']} {stock['curr']}." )else:    print('某些键不存在!')
某些键不存在!


在 if 语句中检查出来 'curr' 不在字典 stock 中,因此运行 else 语句。结果虽然是对的,但是太过冗长。本例中 stock 只有 3 个键,如果有 10 个键呢?




EARP 写法


stock = {'name':'腾讯', 'price':435, 'curr':'港币'}
try:    print( f"{stock['name']}股票价格 {stock['price']} {stock['curr']}." )except KeyError:    print('某些键不存在!')


用 try-block 语句。报错的话应该就是键不存在字典中,这时再处理 KeyError 就完事了。


stock = {'name':'腾讯', 'price':435}
try:    print( f"{stock['name']}股票价格 {stock['price']} {stock['curr']}." )except KeyError:    print('某些键不存在!')
某些键不存在!





4
总结


总结一下:


  • LBYL 先检查再执行,用 if-else 语句

  • EAFP 是不检查出了错再处理,用 try-except 语句

Python 更推荐 EAFP因为


  • 它可读性更强。想想上面 LBYL 检查每个键是否在字典中的场景。

  • 它效率更高。想想 EAFP 只有在出现异常的时候才处理错误,而 LBYL 需要每次运行前都要检查。


其实从 Java 转过来的同学应该更习惯 LBYL 。Java 是强类型 ( strong typing) 语言,对变量类型要求非常严格,它假设你应该知道什么时候应该用什么类型变量,应该怎么用,而 Python 是动态类型 (dynamic typing),即你不需要知道变量是什么类型,只需要知道用了这个变量之后能得到什么结果(Duck Typing)。对于编程严谨性来说,LBYL 是更好的选择,因为严谨的系统容不得做到半路才出现异常 (exception)。 


LBYL EAFP 是两种编程风格,或两种编程哲学,没有对或不对,只有喜欢或不喜欢。



Stay Tuned!


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/64229
 
392 次点击