【问题标题】:Passing a function as a named argument for conditional checking将函数作为命名参数传递以进行条件检查
【发布时间】:2014-04-11 17:12:19
【问题描述】:
def basket(name, colour, smell, rotten=None):
    if rotten:
        if rotten():
            return "Can't eat!"

    return ("The fruit, {}, is {} in colour"
            "and smells like {}.".format(name, colour, smell))

在上面的示例代码中,参数rotten(如果提供)在调用之前会被检查。它必须是一个返回布尔值的函数(为简单起见,没有参数)。它使用两行代码,我不确定这是否是此过程的常规样式。我想到的另一种方法是将当前的替换为:

def basket(name, colour, smell, rotten=lambda: None):
    if rotten():  # Saved a line here
        return "Can't eat!"

    return ("The fruit, {}, is {} in colour"
            " and smells {}.".format(name, colour, smell))

lambda 方法节省了一行;除此之外,我不知道哪个比另一个有优势。这样做的最佳方法是什么?它在标准库代码的任何地方都可以找到吗?

【问题讨论】:

    标签: python function lambda arguments


    【解决方案1】:

    您可以像第一个示例一样保持函数签名不变,并利用boolean operations's short circuit behavior 将其变成这样的一行:

    def basket(name, colour, smell, rotten=None):
        if rotten and rotten():
            return "Can't eat!"
    
        return ("The fruit, {}, is {} in colour"
                "and smells like {}.".format(name, colour, smell))
    

    如果rottenNone,则and 表达式将因短路而失败而不会调用rotten()。如果rotten 不是None,它将继续调用rotten() 并成功谓词为True

    注意:如cmets中所述,您也可以使用函数callable(),并在实际调用之前检查是否可以调用rotten

    if callable(rotten) and rotten():
    

    rotten 不是None 但不是可调用对象(例如传递rotten=True)时,这将保护您的函数不会引发异常。否则,如果您希望函数在传递不可调用时大声抱怨,那么就让它保持原样。

    【讨论】:

    • 最好把它写成if callable(rotten) and rotten():,这样可以确保rotten是一个函数。否则,用户可以将rotten 设为True1 并获得TypeError
    • 我会将其作为附注包含在答案中,但也许 OP 更喜欢在传递不可调用时,函数会大声抱怨。这可能取决于设计。无论如何感谢您的赞赏。
    • 那么,lambda 方法被证明没有什么特别的好处,是吗?使用 lambda,我或许可以通过将 lambda: None 更改为 lambda: True 来更改默认行为,但我不确定这是否是一种 Python 方式。
    • 这取决于您要完成的工作。您可以保留 lambda 版本,恕我直言,与其他方法相比,它没有特别的优势。函数的用户仍然可以传递无效的rotten 并使代码失败。这几乎是一样的。我喜欢rotten=None 方法,因为None 经常用于表示缺少带有命名参数的参数。
    • 另外,如果你使用rotten=lambda: None。您将使用更多内存(虽然不是那么多:),因为该函数将定义 default lambda 并将其保留到程序结束。使用None,这不会发生,因为None 对象是全局引用的,并且在程序开始时已经定义。
    猜你喜欢
    • 2011-12-24
    • 2011-11-02
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多