2013-07-22 29 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 
相关问题