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風格則可以確保原子性

上面參考了部分博文。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM