本文含 2019 字,2 图表截屏
建议阅读 6 分钟
本文是听说你会玩 Python 系列的第四篇
2 - 99% 的人会做错的题
3 - 深挖变量
4 - LBYL vs EAFP
引言
写了 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!