分析函数内部的“ return”语句

时间:2018-07-20 13:37:54

标签: python return code-analysis

有时在一个函数中,我们需要多次使用return语句。

当开发人员更改内部具有多个返回值的函数时,很容易查看“隐藏”另一个返回值的代码的某些部分。 如果单元测试不能涵盖所有可能的路径,那么灾难就可以得到保证-这只是时间问题。

def my_function():
    '''Multiple "return" inside'''

    if condition 1:
        return 1, 2, 3
    if condition 2:
        return 2, 3, 4

    return 5  # this is wrong: only 1 value returned, while 3-tuple expected

让我们在这里假设:最后一次返回是错误的,因为其他调用者期望元组为3。

我想知道您是否知道一种简单的方法来自动捕获这些代码部分吗?我以为可以使用AST,但是找不到任何有用的示例。

此问题与自动代码分析有关,并列出了发现的此类情况-可能与运行单独的脚本有关。

当然,我可以编写一个尝试猜测的解析器(例如regex),然后“手动”检查所有不清楚的情况,但是也许有一种更简单的方法...

3 个答案:

答案 0 :(得分:1)

根据您所使用的Python版本以及您真正想要实现的功能,可以使用多种方法来重构代码。

一种已经建议的方法是在Python 3中使用Type Hints

另一种方法是重构代码,以便调用其他处理这些条件并返回适当值的原子方法,而不是使用多个return语句。您可以在这些原子方法中使用异常处理来确保输出是所需的,或者如果最终返回类型是意外的,则引发异常。

def my_function():
    '''Multiple "return" inside'''

    if condition 1:
        output = func_handle_condition_one()
    if condition 2:
        output = func_handle_condition_two()

    output = some_other_value

    if type(output) is not tuple:
        raise TypeError("Invalid type for output")
    return output

此外,请确保您使用的结构适合您的条件(例如,您要使用多个if还是if-elif-else结构)。您甚至可以重构调用代码以调用正确的函数,而不用调用具有太多条件语句的函数。

答案 1 :(得分:0)

为什么不设置最后返回的变量并检查其长度

def my_function():
    '''Multiple "return" inside'''

    return_value=(0,0,0)

    if condition 1:
        return_value=(1, 2, 3)
    elif condition 2:
        return_value=(2, 3, 4)
    else:
        return_value=5  # this is wrong: only 1 value returned, while 3-tuple expected

    try:
        if len(return_value)==3:
            return return_value
        else:
            print("Error: must return tuple of length 3")
    except:
        print("Error: must return tuple")

答案 2 :(得分:0)

我对结果的最终类型检查的建议是:

assert isinstance(return_value, tuple) and len(return_value) == 3

优点:由于断言在调试阶段之后很容易关闭;制定期望仍然简洁明了。