2015-05-29 43 views
-2

說你有10+條件必須是真實的是有沒有更好的方式來寫:如何訂購帶條件負載的long if語句?

if condition1 and condition2 and condition3 and condition4.......: 
    return value 

與附加的約定,他們不可能全部被提前評估,必須按順序運行。 condition1需要爲true才能運行,否則會出錯。

什麼,我試圖阻止是

test = False 
if all([test, test.func(returns either true or false)]): 
    pass 
= AttributeError: 'bool' object has no attribute 'func' 

模仿此功能

if condition1: 
    if condition2: 
     ...... 
     if condition13: 
      return True 
+2

什麼是condtiions? –

+0

你是否試圖檢查名稱是否存在,然後檢查它是否具有某些屬性等...?這有點模糊 –

+0

仍然不清楚......你總是保證'test.func()'?如果你不這樣做 - 這是否意味着它是'假'? –

回答

3

您可以使用內置的all()(這需要表達的迭代):

if all([condition1, condition2, ...]): 
    return value 

表達式按順序進行評估(因爲all()需要一個迭代),所以在這個例子中從左到右帶有一個列表。

只要all()遇到第一個計算結果爲False的表達式,它就會短路並停止從可迭代表達式中提取表達式。如果你的表達式評估費用很高,你可以通過傳遞一個生成器來代替預先構建的序列來使用它。


下面是一個更高級的例子,爲了使用generator要利用短路,以避免以後評估表達式:

def fail(): 
    raise Exception("Boom") 

def conditions(): 
    yield 1 == 1 
    yield 2 == 42 
    yield fail() 

if all(conditions()): 
    print "All True" 
else: 
    print "Not all True" 

所以調用conditions()將返回一個發電機對象。迭代該生成器將導致該函數中的代碼運行到第一個yield語句,然後在yield返回結果作爲第一個項目之後評估表達式。然後在生成的代碼被暫停,直到all()拉的下一個值,這將恢復代碼並運行它遇到下一個yield聲明,直到等

因此這將永遠不會調用fail()因爲2 == 42後,將評估爲False並且all()將停止迭代生成器。

+1

它不會短路,因爲條件將全部被評估 –

+0

如果a和b以及c和d ......一旦碰到一個「假」,它就不會停止,因爲那麼整個事情就是假。正如「如果a或b或c或d ...'一旦碰到」真「'就停下來。正確? –

+0

@DougR。正確。 – Shashank