【问题标题】:Python assignment and test of function using elif使用 elif 的 Python 分配和函数测试
【发布时间】:2013-07-21 01:40:25
【问题描述】:

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

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

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

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

但是,如果我们按照初始的 if 进行操作,则使用 elif 会导致不必要的 temp 计算。

我可以看到一个解决方案

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

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

【问题讨论】:

  • 如果您不想调用myFunction(bar) 两次,并且您只能在检查foo 后调用它,那么除了使用中间变量来存储结果。没有什么魔法可以解决这个基本的逻辑问题:-)。我认为一个解决方案在反映正确的逻辑时并不难看。您只需要小心将最后一个 elif 放在哪里。
  • 但是if(至少在示例中)无论如何都包含return,所以您可以只使用一个临时值并开始一个新的if 块.

标签: python if-statement variable-assignment


【解决方案1】:

如果您经常这样做,那么拥有memoizing decorator 可能会有所帮助。当前在标准库中(对于较新的 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

【讨论】:

  • “如果你经常这样做”是这里的重点。否则整个方法就是 OTT。
【解决方案2】:

如果您不想调用 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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      你也可以像这样创建一个函数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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-28
        • 1970-01-01
        • 2021-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-15
        相关资源
        最近更新 更多