前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >听说你会玩 Python 系列 4 - LBYL vs EAFP

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

作者头像
用户5753894
修改2020-06-05 14:36:46
1.1K0
修改2020-06-05 14:36:46
举报
文章被收录于专栏:王的机器王的机器

本文含 2019 字,2 图表截屏

建议阅读 6 分钟

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

引言

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

  • LBYL - Look Before Your Leap:三思后行
  • EAFP - Easier to Ask Forgiveness than Permission:先斩后奏

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

  • 前者是谨慎型,在程序执行之前做好检查,代码不 pythonic。
  • 后者是飘逸型,相信程序大概率对的,错了再处理,代码很 pythonic。

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

两个例子

列表例子

代码语言:javascript
复制
l = [1, 2, 3]

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

LBYL 写法

代码语言:javascript
复制

if len(l) >= 3:
    print(l[2])
else:
    print('该索引不存在!')
代码语言:javascript
复制
3

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

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

代码语言:javascript
复制

l = [1, 2]

if len(l) >= 3:
    print(l[2])
else:
    print('该索引不存在!')
代码语言:javascript
复制
该索引不存在!

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

EARP 写法

代码语言:javascript
复制
l = [1, 2, 3]
代码语言:javascript
复制

try:
    print(l[2])
except IndexError:
    print('该索引不存在!')
代码语言:javascript
复制
3

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

代码语言:javascript
复制
l = [1, 2]
代码语言:javascript
复制

try:
    print(l[2])
except IndexError:
    print('该索引不存在!')
代码语言:javascript
复制
该索引不存在!

字典例子

代码语言:javascript
复制
stock = {'name':'腾讯', 'price':435, 'curr':'港币'}

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

LBYL 写法

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

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

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

代码语言:javascript
复制
stock = {'name':'腾讯', 'price':435}
代码语言:javascript
复制

if 'name' in stock and 'price' in stock and 'curr' in stock:
    print( f"{stock['name']}股票价格 {stock['price']} {stock['curr']}." )
else:
    print('某些键不存在!')
代码语言:javascript
复制
某些键不存在!

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

EARP 写法

代码语言:javascript
复制
stock = {'name':'腾讯', 'price':435, 'curr':'港币'}
代码语言:javascript
复制

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

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

代码语言:javascript
复制
stock = {'name':'腾讯', 'price':435}
代码语言:javascript
复制

try:
    print( f"{stock['name']}股票价格 {stock['price']} {stock['curr']}." )
except KeyError:
    print('某些键不存在!')
代码语言:javascript
复制
某些键不存在!

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!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 王的机器 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档