EAFP和LBYL 两种防御性编程风格

EAFP:Easier to ask for forgiveness than permission
获得事后原理总是比事先得到许可要容易的多。

这个EAFP在python中表现的比较多。EAFP,This common Python coding style assumes
the existence of valid keys or attributes and catches exceptions if the
assumption proves false. This clean and fast style is characterized by the
presence of many try andexcept statements. The technique
contrasts with the LBYL style common to many other
languages such as C.

LBYL:

Look before you
leap. 跳跃This coding style explicitly tests for pre-conditions before
making calls or lookups. This style contrasts with the EAFP approach
and is characterized by the presence of
many if statements.

In a multi-threaded environment, the LBYL approach can risk
introducing a race condition between “the looking” and “the leaping”. For
example, the code, if key in mapping: return mapping[key] can fail if another thread
removes key from mapping after the test,
but before the lookup. This issue can be solved with locks or by using the EAFP
approach.

在多线程编程中,LBYL能导致竞争状态。例如:if key in mapping:return
mapping[key]会失败如果另一个线程在测试后移除了key。这个问题能够通过通过锁结局或使用EAFP.

检查数据可以让程序更健壮,用术语来说就是防御性编程。
检查数据的时候,有这样的两种不同的风格。
LBYL:Look
Before You Leap  
EAFP:It‘s Easier to Ask Forgiveness than
Permission 
LBYL即事先检查。
EAFP是不检查,出了问题由异常处理来处理。

下面通过一个单词统计的例子来阐释一下。


d = {}
words = [‘a‘,‘d‘,‘a‘,‘c‘,‘b‘,‘z‘,‘d‘]
#LBYL
for w in words:
if w not in d:
d[w] = 0
d[w] += 1

#EAFP
for w in words:
try:
d[w] += 1
except KeyError:
d[w] = 1

这两种风格各有好坏。
对于LBYL,容易打乱思维,本来业务逻辑用一行代码就可以搞定的。却多出来了很多行用于检查的代码。防御性的代码跟业务逻辑混在一块降低了可读性。
而EAFP,业务逻辑代码跟防御代码隔离的比较清晰,更容易让开发者专注于业务逻辑。
不过,异常处理会影响一点性能。因为在发生异常的时候,需要进行保留现场、回溯traceback等操作。但其实性能相差不大,尤其是异常发生的频率比较低的时候。
还有一点要注意的是,如果涉及到原子操作,强烈推荐用EAFP风格。比如我某段程序逻辑是根据redis的key是否存在进行操作。如果先if
exists(key),然后do
something。这样就变成2步操作,在多线程并发的时候,可能key的状态已经被其他线程改变了。而用EAFP风格则可以确保原子性。

上面参考了部分博文。

EAFP和LBYL 两种防御性编程风格,布布扣,bubuko.com

时间: 2024-10-25 21:11:23

EAFP和LBYL 两种防御性编程风格的相关文章

[转] LBYL与EAFP两种防御性编程风格

检查数据可以让程序更健壮,用术语来说就是防御性编程.检查数据的时候,有这样的两种不同的风格.LBYL:Look Before You Leap  EAFP:Easier to Ask Forgiveness than Permission LBYL即事先检查.EAFP是不检查,出了问题由异常处理来处理. d = {} words = ['a','d','a','c','b','z','d'] #LBYL for w in words: if w not in d: d[w] = 0 d[w] +

python制作电脑定时关机办公神器,另含其它两种方式,无需编程!

小编本人目前就是在电脑面前工作,常常会工作到凌晨两三点还在为自己的梦想奋斗着.有时在办公椅上就稀里糊涂睡着了,我相信有很多朋友和我一样,这样是很不好的.第一对身体不好,第二对电脑不好. 对身体方面,小编也只能说大家年轻的时候千万要对自己好点,特别是在电脑面前工作的朋友,不然以后身体毛病变多,就很难受了.像我才二十多岁,现在坐两个小时就会背部发麻,股椎那里也有轻微疼痛,所以各位朋友千万要注意这一点. 对电脑不好,虽然你已经没有在使用它,但是电脑却一直在工作,CUP一直在运转,它就像我们的人脑一直在

两种高效的并发模式(半同步/半异步和领导者/追随者)

一.并发编程与并发模式 并发编程主要是为了让程序同时执行多个任务,并发编程对计算精密型没有优势,反而由于任务的切换使得效率变低.如果程序是IO精密型的,则由于IO操作远没有CPU的计算速度快,所以让程序阻塞于IO操作将浪费大量的CPU时间.如果程序有多个线程,则当前被IO操作阻塞的线程可主动放弃CPU,将执行权转给其它线程.(*IO精密型和cpu精密型可以参考此文:CPU-bound(计算密集型) 和I/O bound(I/O密集型)) 并发编程主要有多线程和多进程,这里我们先讨论并发模式,并发

Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition

在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权.因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去.因此,一般情况下,当队列满时,会让生产者交出对临界资源的占用权,并进入挂起状态.然后等待消费者消费了商品,然后消费者通知生产者队列有空间了.同样地,当

5种主要的编程风格和它们使用的抽象

大部分程序员使用一种编程语言,并只使用一种编程风格.他们使用的编程方式是所用语言强加给他们的.通常,他们没有机会换一种方式来思考问题,因此难以看到选择更适合手上问题的编程风格所带来的好处. 面向过程  算法 面向对象  类和对象 面向逻辑  目标,通常以谓词演算的方式表示 面向规则  如果-那么规则 面向约束  不变的关系 没有一种编程风格是适合所有类型的应用的.例如,面向规则的编程可能最适合设计知识库,而面向过程的编程可能最适合设计计算密集的操作.面向对象风格最适合的应用范围最广,实际上,这种

Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程

Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程 这里的函数式编程的设计以muduo为例进行对比说明: Reactor实现架构对比 面向对象的设计类图如下: 函数式编程以muduo为例,设计类图如下: 面向对象的Reactor方案设计 我们先看看面向对象的设计方案,想想为什么这么做: 拿出Reactor事件驱动的模式设计图,对比来看,清晰明了: 从左边开始,事件驱动,需要一个事件循环和IO分发器,EventLoop和Poller很好理解:为了让事件驱动支持多平台,Poller上加

QFileDialog保存打开对话框有两种风格: 在Windows和MacOS X平台上提供本地的对话框 Qt自绘的对话框

1.打开对话框两种风格 (1)本地风格         QFileDialog *fileDialog =new QFileDialog(this);         fileDialog->setWindowTitle(tr("Open Image"));         fileDialog->setDirectory(".");         fileDialog->setFilter(tr("Image Files(*.jpg

描述性编程的两种写法

对象库编程(ORP)是一个非常强大的功能,如果对象名字改变了,只需要进入对象库修改对象,脚本即可批量更新. 描述性编程(DP)不需要维护庞大的对象库,而需要维护庞大的代码,但是在某些情况下(比如对象不能添加到对象库)它很有用. 下面通过一个例子来学习如何进行描述性编程: 首先,我们录制一段在百度首页输入“abcde”,然后点击“百度一下”的代码: Browser("百度一下,你就知道").Page("百度一下,你就知道").WebEdit("wd"

几种编程风格简介

面向对象,面向过程,函数式编程,声明式编程 都是一种编程风格: 一.函数式编程lisp就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,模拟数学上的函数,,任意一个函数, 只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用. 函数式编程的特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数! 不会修改外部参数或变量的值 精简 可读性差 python 不是一个完全意义上的函数式编程语言,只是引用了 函数式编程的风格 比如 map reduce fi