简体   繁体   English

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

[英]Analyze 'return' statement inside function

Sometimes inside one function we need to use the return statement several times. 有时在一个函数中,我们需要多次使用return语句。

When developer changes a function with multiple returns inside, it's easy to oversee some parts of code where yet another return was "hidden". 当开发人员更改内部具有多个返回值的函数时,很容易查看“隐藏”另一个返回值的代码的某些部分。 If unit tests do not cover all possible paths, disaster is guaranteed - it's only a question of time. 如果单元测试不能涵盖所有可能的路径,那么灾难就可以得到保证-这只是时间问题。

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

Let's assume here: last return is wrong, because other callers expect tuple of 3 items. 让我们在这里假设:最后一次返回是错误的,因为其他调用者期望3项的元组。

I wonder if you know an easy way how to catch such parts of code automatically? 我想知道您是否知道一种简单的方法来自动捕获这些代码部分吗? I thought I could use AST, but I could not find any useful example of this. 我以为可以使用AST,但是找不到任何有用的示例。

This question is about automatic code analysis and listing such cases found - could be with running a separate script. 这个问题是关于自动代码分析并列出发现的此类情况的-可能与运行单独的脚本有关。

Of course I could write a try-to-guess parser (with eg regex) and then 'manually' check all unclear cases, but maybe there is a simpler way... 当然,我可以编写一个尝试猜测的解析器(例如regex),然后“手动”检查所有不清楚的情况,但是也许有一种更简单的方法...

Depending on what version of Python you're using and what you really want to achieve, there are several ways to refactor the code. 根据所使用的Python版本以及您真正想要实现的功能,可以使用多种方法来重构代码。

One way, as has been already suggested, is to use Type Hints in Python 3. 正如已经建议的那样,一种方法是在Python 3中使用类型提示

Another way is refactor your code such that instead of using multiple return statements, you call other more atomic methods that handle those conditions and return the appropriate values. 另一种方法是重构代码,以便调用其他处理这些条件并返回适当值的原子方法,而不是使用多个return语句。 You use exception handling in those atomic methods to make sure the output is as desired, or raise an exception if final return type is unexpected. 您可以在那些原子方法中使用异常处理来确保输出是所需的,或者如果最终返回类型是意外的,则引发异常。

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

Additionally, ensure that you're using the right constructs for your conditions (such as whether you want to use multiple if or the if-elif-else construct). 此外,请确保您为条件使用了正确的构造(例如,是否要使用多个ifif-elif-else构造)。 You could even re-factor your calling code to call the right function instead of calling one that has so many conditional statements. 您甚至可以重构调用代码以调用正确的函数,而不用调用具有很多条件语句的函数。

Why not set a variable that gets returned at the end and check for its length 为什么不设置最后返回的变量并检查其长度

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")

My proposal for the final type check of the result would be: 我对结果的最终类型检查的建议是:

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

Advantage: as assert is easily switched off after debugging phase; 优点:断言在调试阶段后很容易关闭; still succinct statement for formulating the expectation. 对于期望的表述仍然很简洁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM