将函数作为条件检查的命名参数传递

时间:2014-04-11 17:12:19

标签: python function lambda arguments

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方法保存一行;除此之外,我不知道哪一个优于另一个。这样做的最佳方式是什么?是否可以在标准库代码中的任何位置找到它?

1 个答案:

答案 0 :(得分:2)

您可以像第一个示例中那样保留函数签名,并利用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将会成功。

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

if callable(rotten) and rotten():

rotten不是None但不是可调用对象(例如,传递rotten=True)时,这将保护您的函数免于异常上升。如果不通过,你会更喜欢在非callable通过时大声抱怨的功能,那就让它原样吧。