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

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

  1. d = {}
  2. words = [‘a‘,‘d‘,‘a‘,‘c‘,‘b‘,‘z‘,‘d‘]
  3. #LBYL
  4. for w in words:
  5. if w not in d:
  6. d[w] = 0
  7. d[w] += 1
  8. #EAFP
  9. for w in words:
  10. try:
  11. d[w] += 1
  12. except KeyError:
  13. d[w] = 1

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

时间: 2025-01-01 23:16:10

[转] LBYL与EAFP两种防御性编程风格的相关文章

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

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

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

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

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

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

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

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

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

描述性编程的两种写法

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

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

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

浅析C# 异步编程的两种方式

一.传统BeginInvoke方式. BeginInvoke方法用于启动c#异步调用.它返回IasyncResult,可用于监视调用进度.EndInvoke方法用于检索c#异步调用结果. 调用BeginInvoke后可随时调用EndInvoke方法;如果C#异步调用未完成,EndInvoke将一直阻塞到C#异步调用完成. 总结其使用大体分5个步骤: 1.声明委拖 2.创建异步方法 3.实例化委拖(把委拖与方法关联)  A 4.通过实例的BeginInvoke调用异步方法 5.通过实例的EndIn

JavaScript强化教程——DOM编程(两种控制div移动的方法)

本文为H5EDU机构官方HTML5培训教程,主要介绍:JavaScript强化教程--DOM编程(两种控制div移动的方法) 第一种 按钮控制首先 创建两个html按钮和一个div并给div一个样式 input type="button" value="左" id="1"> <input type="button" value="右" id="2"> <div i