2013-07-22 30 views
12

我已經看到了問題的功能測試。我有一個表達Python的分配和使用與此類似,但並不完全相同的elif

if foo == .... 
    return -1 
elif myFunction(bar) != -1: 
    return myFunction(bar) 
elif ... 

我不想計算​​兩次。如果是單純的if,我可以做

temp = myFunction(bar) 
if temp != -1 
    return temp 

但是這樣做有elif將導致temp不必要的計算,如果我們跟着初使if

我可以使用

if ... 
else 
    temp = myFunction(bar) 
    if temp != -1: 
    return temp 
    elif ... 

看到一個解決方案,但現在開始變得更加難看。有沒有更好的方法來完成這一點?

+0

如果你不想叫'myFunction的(酒吧)'兩次,如果你只能/要檢查你的'foo'後調用它,那麼就比使用一箇中間變量來存儲結果沒有別的辦法,沒有魔法來解決這個基本邏輯問題:-)。我認爲一個解決方案在反映正確的邏輯時並不難看。你只需要小心放置最後一個'elif'的位置。 –

+2

但是'if'(至少在本例中)含有'反正return',所以你可以* *只使用一個臨時的價值,並開始一個新的'if'塊。 – Volatility

回答

6

如果你這樣做了很多,它可能會支付有一個memoizing decorator左右。這是目前在標準庫(較新的Python 3.X)唯一memoizer是lru_cache,這是矯枉過正,但顯示的總體思路:

>>> def func(): 
...  print("foo") 
...  return 1 
... 
>>> if func(): 
...  print(func()) 
...  
foo 
foo 
1 

現在memoize的func

>>> from functools import lru_cache 
>>> func = lru_cache(1)(func) 
>>> if func(): 
... print(func()) 
...  
foo 
1 
+0

+1,打敗了我,沒有重新發明車輪。 –

+0

「如果你這樣做了很多」是這裏的關鍵點。否則,整個方法只是OTT。 –

1

如果你的函數調用很簡單,你可以繼續調用兩次。 Python不支持分配和比較功能。所以,你必須權衡可讀性/優雅性能。

5

如果您不想打電話給myFunction的(酒吧)兩次,然後有比使用一箇中間變量結果存儲在沒有其他辦法。這裏的人們開始提出這個複雜的緩存解決方案。在極端情況下,這可能非常方便,但在此之前,讓我們回到基礎知識。你應該正確使用你想從你的條件塊中返回的事實。在這些情況下,您可以節省很多else。現在做什麼如下基本上是從你的問題的代碼塊,但沒有網點,適當的縮進,並與名稱根據PEP8:

if foo == "bar" 
    return -1 
elif myfunction(bar) != -1: 
    return myfunction(bar) 
else 
    return None 

它可以很容易地進行更換:

if foo == "bar" 
    return -1 
t = myfunction(bar) 
if t != -1: 
    return t 
return None 

如前所述在另一個答案中指出,如果它不影響代碼的性能,可以調用你的函數兩次。結果看起來那樣簡單

if foo == "bar" 
    return -1 
if myfunction(bar) != -1: 
    return myfunction(bar) 
return None 
0

你也可以做一個函數promise這樣的:

class Promise(): 
    def __init__(self, func): 
     self.__func = func; 
     self.__computed = False; 

    def Get(self): 
     if not self.__computed: 
      self.__result = self.__func() 
      self.__computed = True 
     return self.__result 

def func(text): 
    print text 
    return 1 

    f = Promise(lambda: func("compute")) 
    >>> f.Get()  # first call, compute 
    compute 
    1 
    >>> f.Get()  # second call, return result 
    1 
相關問題