【问题标题】:What is the most pythonic way to conditionally return a function有条件返回函数的最pythonic方法是什么
【发布时间】:2014-09-06 02:43:10
【问题描述】:

假设我有 2 个功能。我希望 func2 返回 func1,除非 func1 返回 None,在这种情况下 func2 返回其他内容。有两种方法可以做到这一点,但它们都感觉有点不对。

我可以说:

def func1(n):
    if (condition):
        return foo

def func2(n):
    if func1(n) is not None:
        return func1(n)
    else:
        return something_else

但这感觉不对,因为我必须调用 func1(n) 两次(而 func1(n) 是一个更大的计算)。为了解决这个问题,我可以说:

def func1(n):
    if (condition):
        return foo

def func2(n):
    foo = func1(n)
    if foo is not None:
        return foo
    else:
        return something_else

但这感觉不对,因为我认为我不应该分配一个永远不会再次使用的新变量,只是为了检查 func1 是否返回 None。

有没有一种更简单的方法可以做到这一点,我不必调用 func1 两次,也不必创建新变量?如果这是唯一的方法,你会推荐这两种方法中的哪一种?我目前使用第二种方式(我将 foo 设置为 func1 返回的内容,而不是 return foo 除非 foo == None)

另外,请记住,在我的真实代码中,我调用了几个不同的函数,我想返回第一个不是 None 的函数,这只是一个更简单的代码版本,可以解决问题。

【问题讨论】:

  • 你应该使用is和is not而不是==和!=,对于像None这样的单例。所以说文档。 stackoverflow.com/questions/2209755/python-operation-vs-is-not
  • 请不要使用== True; if condition: 就足够了,而且不容易出错(作为比较链,如果添加其他比较,可能会产生错误的表达式)。
  • 另外,如果您要检查类型,请使用isinstance
  • 好的,请记住,这不完全是我的代码,而是我编写的更简单的代码,以显示我正在尝试做的事情。

标签: python function return conditional-statements


【解决方案1】:

由于None 的计算结果为False,您可以这样做:

def func2(n):
    return func1(n) or something_else

但是应该注意的是,如果func1(n) 返回任何错误信息(0、[] 等),这将导致 func2 返回 something_else


对于许多功能,您可以使用next 和一些generator expressions:

def myfunc(n):
    vals = (f(n) for f in (func1, func2, func3...))
    return next((v for v in vals if v is not None), something_else)

【讨论】:

  • 如果你需要从func1(n)返回虚假信息,请执行ret = func1(n); return ret if ret is not None else something_else
  • 嗯,也许我应该在问题中指定这个,但我有很多不同的功能,我想返回第一个不是 None 的功能。我想我可以做到return func1(n) or func2(n) or func3(n) or something_else
【解决方案2】:

为调用 func1 的结果命名相对便宜,所以我会这样做,但要像这样编写函数:

def func2(n):
    ret = func1(n)
    return ret if ret is not None else something_else

【讨论】:

    【解决方案3】:

    您绝对不想两次调用func1 - 除了效率低下之外,func1 可能会产生副作用或根据当时的状态产生略有不同的答案。

    另外,return 之后不需要else,因为return 退出了函数。

    您的第二个选项的修订版本是:

    def func1(n):
        if condition:
            return foo
    
    def func2(n):
        foo = func1(n)
        if foo is None:
            return something_else
        return foo
    

    请注意,即使 'func1' 返回一个错误值,这仍然有效。

    或者,注意func1 的内容,你能做到吗:

    def func1(n):
        return foo
    
    def func2(n):
        foo = func1(n)
        if condition:
            return foo
        return something_else
    

    这要看func1的真实内容到底是什么。

    【讨论】:

    • 我知道 else 是不必要的。此外,您的修订版基本上就是我现在的代码,我只是想知道创建变量 foo 是否绝对需要。另外,func1 的内容太复杂了,无法将condition 添加到 func2 中,尤其是看到 func1 的条件如何调用其他函数,并返回 那些 不返回的函数中的第一个没有。
    • 如果 iCodez 回答的限制有问题,我想不出任何方法来避免创建变量 foo。
    【解决方案4】:

    根据您对 iCodez 的评论,与我之前的回答完全不同:

    def func1(n):
        return ham
    
    def func2(n):
        return jam
    
    def func3(n):
        return spam
    
    def mainfunc(n):
        for f in (func1, func2, func3):
            foo = f(n)
            if foo is not None:
                return foo
    

    【讨论】:

      猜你喜欢
      • 2014-05-22
      • 2020-06-22
      • 2019-06-28
      • 1970-01-01
      • 1970-01-01
      • 2010-10-04
      • 2014-07-10
      • 2014-12-30
      • 2020-11-20
      相关资源
      最近更新 更多