社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

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

王的机器 • 5 年前 • 553 次点击  




本文含 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
 
553 次点击