嵌套if子句vs级联返回vs断言

时间:2017-12-25 21:23:39

标签: python if-statement control-flow

当if子句中的否定评估将导致函数/方法内部进行return调用时,Python中更推荐使用嵌套if子句或利用逆向评估并调用函数返回? e.g:

if required_condition_1:
    if required_condition_2:
        if required_condition 3:
            pass
        return 'error for condition 3'
    return 'error for condition 2'
return 'error for condition 1'

或者:

if not required_condition_1:
    # preparation...
    return 'error for condition 1'

if not required_condition_2:
    # preparation...
    return 'error for condition 2'

if not required_condition_3:
    # preparation...
    return 'error for condition 3'

# if runtime reaches this point it means that it has passed all conditions

想象一下,您必须注册一个用户,并且您需要满足各种条件。只有在满意的情况下才会注册用户,但错误消息取决于失败的条件。

我的猜测是,在其他情况下,正如用户在答案部分中提到的那样,如果某个条件失败,则可以应用其他操作。然后我想我应该嵌套ifs。但是,我只会返回一条错误消息,所以我认为第二种选择更可取。

我也考虑过断言:

try:
    assert(required_condition_1)
    try:
        assert(required_condition_2)
        # do tasks
    except AssertionError:
        # error for condition 2
except AssertionError:
    # error for condition 1

尽管我认为最后一种方式并不像处理异常那样值得推荐。同时作为SO用户mentions

  

如果代码正确,则禁止单事件干扰,硬件故障   等等,没有断言会失败。这就是为什么的行为   不得影响最终用户的程序。尤其是断言   即使在特殊的程序条件下也不会失败。它只是   永远不会发生。如果它发生了,程序员应该被摧毁   为了它。

我知道这似乎主要是基于意见的,但对我而言,因为所有语言都有样式指南,可以产生更具可持续性,可扩展性和可读性的环境它的特点和功能。我想知道如果有一种推荐的方法可以在方法中处理这个问题,并且最重要的是,为什么

2 个答案:

答案 0 :(得分:3)

虽然这可以被视为基于意见,但我认为客观地第二种方式似乎更具可读性。

在您的第一个示例中,有人在阅读您的代码时必须解密,因为每个语句在逻辑上与它嵌套的语句无关,这是您不希望发生的事情。通常,嵌套块意味着某种继承逻辑。

第二个例子写得更整齐,并且不需要太多考虑来实现逻辑的流程。你想要应用的条件越多越深入,而不是越来越深入,逻辑流程似乎暗示每个人都应该满意。

第一种风格有其用例,不适用于手头的给定任务:条件检查。

至于你的第二个问题,在这个用例中使用断言是不合适的。根据经验,只有在永远不会出错的情况下才使用assert,但对于程序执行非常重要,会出错。其中一个最明显的用途是编写测试用例,一个函数应该给出一定的输出,如果它没有给你那个输出就很糟糕。

例外情况是您可能会遇到的错误例如除以零错误,属性错误,以及处理用户输入时的错误。

答案 1 :(得分:2)

正如Ziyad Edher回答的那样,第二个更具可读性:

if not required_condition_1:
    # preparation...
    return 'error for condition 1'

if not required_condition_2:
    # preparation...
    return 'error for condition 2'

if not required_condition_3:
    # preparation...
    return 'error for condition 3'

而且,如果您希望只有return,那么:

if not required_condition_1:
    # preparation...
    _error = 'error for condition 1'

elif not required_condition_2:
    # preparation...
    _error = 'error for condition 2'

elif not required_condition_3:
    # preparation...
    _error = 'error for condition 3'

else:
    _error = None

return _error