2013-09-21 70 views
0

我有以下代碼在var = func()中,是否立即評估func()或何時需要var?

def isIt(arg): 
    isA = funcA(arg) 
    isB = funcB(arg) 

    return (isA and isB) 

其中funcB()的方式比FuncA的更昂貴的計算和超過一半的情況下FuncA的()爲假。

所以,明智的,如果我讓蟒蛇電話funcB只有當FuncA的是真正的由

def isIt(arg): 
    return (funcA(arg) and funcB(arg)) 

那兩個功能相同的,如果國土資源消耗考慮在內?如果funcB()是生成器上的任何(),會怎麼樣?我編寫像第一個代碼的意圖是,funcA()和funcB()這個參數不是arg,它的參數很長,足以破壞可讀性。

ps。我只是意識到我可以使用兩個本地函數而不是變量來達到像第二個代碼一樣的效果。

+0

你能改說這個問題嗎?你想要確定什麼? – smac89

回答

2

那兩個功能相同帳戶?

它們在功能上並不相同。你似乎在這個問題已經明白這一點,所以我不太清楚你的疑惑是什麼,但是當資源消耗被認爲是這一點尤其重要:

你可以做到這一點
def isIt(arg): 
    lightweightResult = lightweightFunction(arg) 
    expensiveResult = superExpensiveFunction(arg) 

    // obviously you can use both results here, so both have been computed. 


    // return the values directly, no further computation done here: 
    return (lightweightResult and expensiveResult) 

原因之一這種方式是,如果你需要expensiveResult作爲別的東西,或者如果superExpensiveFunction總是需要被調用,比如某個資源的初始化器。

在第二種情況下,正如您所描述的那樣,funcB(arg)僅在funcA(arg)評估爲真(返回真實值)時才被評估。這就是所謂的short circuiting

def isIt(arg): 
    return (lightweightFunction(arg) and superExpensiveFunction(arg)) 

短路是衆所周知的是,以防止不必要的執行的好方法。

如果funcB()是生成器上的任何(),會怎樣?

它永遠不會運行生成器,除非被調用。發電機組已經是防止不必要的執行的好方法,因爲它們被懶惰地評估過。在這種情況下,我認爲短路和發電機組是很好的組合。

如由Blkknght的評論指出,這是值得注意的是,any()all()也有短路,所以在發電機,發電機將只進行評估後可以確認結果(全部或真假元素任何)。你可以在python.org...#all看到代碼。

+0

你對發電機的看法很好。如果'funcB'是'any(expensive_generator(lots,of,args))',那麼你可以先調用'gen = expensive_generator(args)'(除了返回生成器對象之外什麼都不會做),然後把任何(gen)'調用將其消耗到短循環的'和'表達式中。也可能值得注意的是,任何短路也是如此,所以如果第一個「真值」在發生器的結果早期,其餘的將不會被讀取。 – Blckknght

+0

@Blckknght很好,謝謝。 – Nicole

0

它們不等價。第一個在每一個案例中都會調用funcAfuncB。如果funcA的結果不是真的,則邏輯OR短路,則第二個將僅調用funcB

1

我將它寫成

def isIt(arg): 
    if not funcA(arg): 
     return False 
    return funcB(arg) 

這是有點長,但符合Python的理念更多。

編輯:使三行而不是五行。

+1

如果我正在閱讀這段代碼,我會奇怪你爲什麼用五行代替'return funcA(arg)和funcB(arg)'來寫它。 – flornquake

+0

這是否與Python哲學更符合? – Nicole

+0

@NikC,「明確比隱含更好」。 – fjarri

0

是的,你是對的調用計算較不昂貴的功能首先

這是我會怎麼寫的功能:如果國土資源消費是考慮到

>>> def isIt(arg): 
...  if funcA(arg): 
...    return funcB(arg) 
...  return 0 
相關問題