HOWTO · Python

修复 Python 在函数外部返回的错误

如何修复 Python 在函数外部返回的错误。

本页内容

如果 Python 报告 SyntaxError: 'return' outside function,请将 return 语句移入函数体。Python 会在解析文件时、程序运行前拒绝模块级的 return。请检查缩进以及周围的 def 代码块;在顶层代码中,应调用函数并使用它返回的值。

理解 return outside function 错误

return 关键字会将一个值从当前函数传回调用它的代码。它在语法上只能出现在函数体内。如果 return 语句出现在模块级,Python 会抛出 SyntaxError,并显示消息 'return' outside function。

Python 会在执行文件之前先解析整个文件。因此,顶层的 return 会导致文件中更早出现的语句也无法运行。错误消息会指向 return 所在行,但原因可能是后面某处的语句位置不正确,或缩进导致函数比预期更早结束。例如,下面这个无效的顶层语句会产生此解析错误:

SyntaxError: ‘return’ outside function

将 return 移入函数

将该语句放在函数中,与其他语句保持相同的缩进层级。然后从模块级代码调用该函数。运行以下示例:

本节中的代码以及显示的标签或输出仍为英文。

def calculate_total(price, quantity):
    return price * quantity

print(calculate_total(8, 3))
24

这里,return price * quantity 属于 calculate_total,而调用时传入了 8 和 3 作为参数。随后,返回值会传给 print。你可以将计算过程和参数替换为自己的函数需要完成的工作。

条件语句或循环本身并不会创建函数。只有当 if、for 或 while 代码块嵌套在函数内时,才能在其中使用 return。下面这个补充示例在语法上有效,但没有包含在所提供的执行证据中:

def first_match(items):
    for item in items:
        if item == "target":
            return item
    return None

print(first_match(["other", "target", "later"]))

return item 这一行同时位于函数和 if 代码块内。找到匹配项后,它会立即退出 first_match,因此函数调用会将 "target" 传给 print。如果没有匹配项,就会执行最后的 return None;如果函数执行到末尾仍没有遇到 return,也会隐式返回 None。

检查缩进和函数定义

Python 使用缩进来判断哪些语句属于函数。与 def 对齐的行位于函数外部;缩进在它下面的行则属于函数体。如果在 def get_value(): 后立即取消缩进,函数就没有函数体,因此 Python 会报告缩进错误,而不是 SyntaxError: 'return' outside function。若要产生所报告的错误,先为函数添加一条有效的函数体语句,例如 pass,再将 return 5 放在最左侧;此时最后一行就是顶层的 return。正确写法会让 return 5 保持缩进,位于 def get_value(): 之下。请使用一致的缩进,通常为四个空格,并检查错误位置上方紧邻的几行,找出函数代码块在哪里结束。

还要确认函数头语法正确,并以冒号结尾。例如,my_function(): 因为缺少 def 而格式错误;Python 会针对函数头报告语法错误,而不会将其视为一个函数并报告其 return 位于函数体外。函数头拼写错误或不完整也可能导致不同的错误消息。先修正函数头,再确认 return 行缩进在函数头之下。诊断的关键是确认该语句是否确实位于函数体内。

在模块级代码中调用函数

模块级代码指 Python 文件中不属于函数或类的部分。它可以调用函数、将返回值赋给变量,然后显示或使用该值。例如,写入 answer = calculate_total(8, 3),再使用 answer;不要在模块级写 return calculate_total(8, 3)。

调试时,请检查 Python 指出的行,以及该行相对于最近的 def 的缩进。如果这一行已经缩进,请向上查找是否有更早取消缩进的行结束了函数体。如果函数定义本身有语法错误,请单独修正。确认 return 位于预期函数中后,再从周围的模块级代码调用该函数。这样可以区分从函数返回值与在程序其余部分使用该值这两件事。