14

我见过与此类似但不完全相同的问题。我有一个表情

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

我不想计算myFunction(bar)两次。如果它只是一个if,我可以做

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

但是,使用 anelif会导致不必要的计算,temp如果我们要遵循 intitial if

我可以看到一个解决方案

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

但现在开始变得更加丑陋。有没有更好的方法来实现这一点?

4

4 回答 4

7

如果你经常这样做,那么周围有一个记忆装饰器可能是值得的。当前在标准库(对于较新的 Python 3.x)中唯一的 memoizer 是 ,这有点lru_cache矫枉过正,但显示了总体思路:

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

现在记住func

>>> from functools import lru_cache
>>> func = lru_cache(1)(func)
>>> if func():
...    print(func())
...     
foo
1
于 2013-07-22T10:58:57.627 回答
7

如果您不想调用 myFunction(bar) 两次,那么除了使用中间变量来存储结果之外别无他法。这里的人们开始为此提出复杂的缓存解决方案。在极端情况下这可能非常方便,但在此之前,让我们先回到基础。您应该正确利用您想要从条件块中返回的事实。在这些情况下,您可以节省许多elses。现在基本上是您问题中的代码块,但没有点,有适当的缩进,并且名称根据 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
于 2013-07-22T11:06:20.677 回答
1

如果你的函数调用足够简单,你可以调用两次。Python 不支持分配和比较功能。因此,您必须在可读性/优雅与性能之间进行权衡。

于 2013-07-22T11:02:19.317 回答
0

你也可以像这样做出一个函数承诺

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
于 2013-07-22T12:27:44.607 回答