如何修复python中不一致的return语句?

时间:2019-02-20 11:08:55

标签: python string list return

我是python的新手,我有一个项目,我正在一个具有两个函数的小型项目,其中第一个函数返回第一次在字符串中发现差异的索引。下一个函数会执行此操作,但是会在字符串列表中。现在,由于我是一个业余爱好者,我使用了过多的if和else语句,这导致了太多的return语句,尤其是在第二个函数中,并且出现了错误[R1710:inconsistent-return-statements]。我该如何解决它?有人可以给我清晰的示例来介绍更好的代码吗?很抱歉这个问题这么久。

IDENTICAL = -1
def singleline_diff(line1, line2):
    """
    Inputs:
        line1 - first single line string
        line2 - second single line string
    Output:
        Returns the index where the first difference between
        line1 and line2 occurs.

        Returns IDENTICAL if the two lines are the same.
    """
    len1 = len(line1)
    len2 = len(line2)
    minimum_length = min(len1, len2)

    if len1 != len2:
        if minimum_length == 0:
            return 0
        for idx in range(minimum_length):
            if line1[idx] == line2[idx]:
                pass
            else:
                return idx
        return idx + 1

    for idx in range(len1):
        if line1[idx] == line2[idx]:
            pass
        else:
            return idx
    return IDENTICAL

def multiline_diff(lines1, lines2):
    """
    Inputs:
      lines1 - list of single line strings
      lines2 - list of single line strings
    Output:
      Returns a tuple containing the line number (starting from 0) and
      the index in that line where the first difference between lines1
      and lines2 occurs.

      Returns (IDENTICAL, IDENTICAL) if the two lists are the same.
    """
    line_no = singleline_diff(lines1, lines2)

    len_lines1, len_lines2 = len(lines1), len(lines2)

    if len_lines1 == len_lines2:

        if (len_lines1 or len_lines2) == 0:
            if len_lines1 == len_lines2:
                return (IDENTICAL, IDENTICAL)
            else:
                idx = singleline_diff(lines1[line_no], lines2[line_no])
                return (line_no, idx)

        else:
            idx = singleline_diff(lines1[line_no], lines2[line_no])

            if line_no == IDENTICAL:
                return (IDENTICAL, IDENTICAL)
            elif line_no != IDENTICAL:
                return (line_no, idx)

    else:
        return (line_no, 0)

2 个答案:

答案 0 :(得分:3)

OP 代码中语义错误的位置在 Abhishek Arya's answer

TL;DR - 提前返回:

def your_function():
    if not should_do():
        return # NO RETURN VALUE!
    # rest of the function

...是的,这将不再发出 inconsistent-return-statements ;)

当您搜索 inconsistent-return-statements 时,此问答也会弹出,我想为这些问题提供一个简短的“常见问题”指南。

案例A:返回值无关紧要,你只想早点退出函数

在某些情况下,有些函数(或“过程”,如果您想了解它的技术)只是做某事,但根本不希望有任何返回值,
同时,可能有例如在函数开始时进行某种检查,此函数运行是否有意义,您可能首先想到的是将整个函数代码包装在一个 if 语句中:

def your_function(article):
    if display_content():
        content = get_content(article)
        # do some extensive logic to generate final content
        # ...
        print(content)

...这过于简单化了,但让我们希望你能想象一下,如果有更多的检查和更多的代码,这样的编码是如何很快落入“意大利面条式代码”的+它还窃取了一个“标签”的您迫切需要适合项目最大行长的空间。

幸运的是,许多其他编程语言一样,有一种方法可以通过 returnANY 放在函数 run 中,意思是在任何 "Control Flow" - 包括 if/elif/else, for/while loops, ...

现在您可能会快速跳转到 return NoneFalse 等。虽然它可以工作,但您仍然会收到 pylint inconsistent-return-statements 警告 - 以了解 为什么让我们看看警告信息:

<块引用>

函数中的所有 return 语句都应该返回一个 表达式,或者它们都不应该。 pylint(不一致的返回语句)

从 pylint 的角度来看,如果您在 return 之后放置任何内容,它将被视为一个表达式。那么该怎么办?实际上,在 Python 中,你可以返回“nothing”(同样,这不是 Python 独有的)

def your_function(article):
    if display_content():
        return

    content = get_content(article)
    # do some extensive logic to generate final content
    # ...
    print(content)

尽管在 Python 中返回“无”应该是(并且从技术上讲,据我所知,它是)等效于 return None,但通过实际编写“None”,您是表达强> 意图,无论其隐含。
不要将此与 pylint(assignment-from-none) (Assigning result of a function call, where the function returns None) 混淆 - 其中 both "return" 和 "return None" 都被考虑作为返回 None

案例 B:你的函数有一个不返回的案例

特别是在较大的代码中,很常见的错误是创建了一个导致根本不返回任何内容的代码部分。这不是完全 OP的情况,因为他们只使用了相同条件的否定,但是pylint不知道,所以这是它的思考过程:

if SOME_CONDITION: # ok, here's just another condition
    return someReturnExpression # and ok, it returns SOMETHING, let's note that
elif OPPOSITE_OF_SOME_CONDITION: # ok, here's just another condition
    return someReturnExpression # and ok, it returns SOMETHING, let's note that
# WAIT ! What?! THERE WAS NO "else:"! Hmmm...
# ...what happens if both conditions fail? NOTHING WOULD BE RETURNED!
# We need to make a warning about that!
# (fact that sometimes they return SOMETHING and sometimes NOTHING)

所以这个 inconsistent-return-statements 可以用

解决
if SOME_CONDITION: # ok, here's some condition
    return someReturnExpression # and ok, it returns SOMETHING, let's note that
else: # ok, here's else
    return someReturnExpression # and ok, it returns SOMETHING, let's note that
# Ok, so if returns SOMETHING, else returns SOMETHING,
# so SOMETHING is returned every time! that's good!

...这本身是有效的,但它会产生另一个pylint问题

<块引用>

"return" pylint(no-else-return) 后不必要的"else"

参见 python 实际上鼓励早期返回,因为它通常会导致代码更清晰。
return 在函数运行期间 ENDS(/exits) 函数 和 pylint 看到 - 它看到如果条件为真,函数代码将简单地结束 - 那又如何它,Abhishek Arya,我和许多其他人建议只是在 if 部分之后继续使用代码:

if SOME_CONDITION:
    return someReturnExpression

# ... some more code ...
# ... some more code ...
return someReturnExpression

案例 C:组合

简单地不要将“只是”returnreturn SOMETHING 结合起来,
如果你真的需要返回None,在这种情况下只需明确return None

def get_article(id):
    article = find_article(id)
    if article.id == 0:
        return None

    return article

这只是一个例子,这不是您真正检查某些文章的方式;)

答案 1 :(得分:0)

在这里查看代码:

if len_lines1 == len_lines2:
    return (IDENTICAL, IDENTICAL)
else:
    idx = singleline_diff(lines1[line_no], lines2[line_no])
    return (line_no, idx)

您可能已经写出了以下内容:

if len_lines1 == len_lines2:
    return (IDENTICAL, IDENTICAL)
idx = singleline_diff(lines1[line_no], lines2[line_no])
return (line_no, idx)

您只是不需要else块来返回此表达式,因为如果控件没有进入if块,则这部分代码将自动被调用。希望对您有所帮助。