在 pylint 文档中,我们读到:
当在以下位置找到单个“return”或“return None”语句时发出 函数或方法定义的结尾。这个声明可以安全地被 删除是因为 Python 将隐式返回 None
在 PLR1711 的 ruff 文档中我们读到:
它有什么作用
检查以不必要的 return 或 return None 结尾的函数,并且不包含其他 return 语句。
听起来像 ruff 的文档中的
unnecessary return or return None
指的是这样的语句,删除后功能实际上将保持不变。
所以 ruff 和 pylint 都应该标记这个返回,对吧?:
def f():
"""docs"""
return None
但他们没有。我在新的 google colab 环境中运行了这个:
!pip install pylint ruff>/dev/null
!pylint --version && ruff --version
!printf "\nDOCS :\n"
!printf 'def f():\n """docs"""\n return None' > a.py
!pylint --disable C a.py
!ruff check --extend-select PLR1711 a.py
!printf "\nPRINT :\n"
!printf 'def f():\n print()\n return None' > a.py
!pylint --disable C a.py
!ruff check --extend-select PLR1711 a.py
并得到:
pylint 3.3.1
astroid 3.3.5
Python 3.10.12 (main, Sep 11 2024, 15:47:36) [GCC 11.4.0]
ruff 0.7.4
DOCS :
------------------------------------
Your code has been rated at 10.00/10
All checks passed!
PRINT :
************* Module a
a.py:1:0: R1711: Useless return at end of function or method (useless-return)
-------------------------------------------------------------------
Your code has been rated at 6.67/10 (previous run: 10.00/10, -3.33)
a.py:3:5: PLR1711 [*] Useless `return` statement at end of function
|
1 | def f():
2 | print()
3 | return None
| ^^^^^^^^^^^ PLR1711
|
= help: Remove useless `return` statement
Found 1 error.
[*] 1 fixable with the `--fix` option.
那么我们可以使用这些工具来抱怨这样的回报吗?
Ruff 使用的确切逻辑在 useless_return.rs 中详细说明,并附有解释每项检查的详细注释。
在这种情况下,看起来 Ruff(可能还有 PyLint)对于(a)仅由
return
语句组成的函数和(b)仅由文档字符串加 return
语句组成的函数有特殊例外。
情况(a)相当明显;函数需要函数体,而
pass
比 return None
更不明确(也更不直观)。情况 (b) 是情况 (a) 的扩展:文档字符串的存在(或不存在)通常不会影响函数的解释方式,并且仅包含文档字符串的函数看起来相当未完成,而函数包含明确的 return None
可以更清楚地表明这是预期的行为。请记住,lint 规则通常是实用的,而不是绝对的。这就是规则存在例外的原因。如果这让您感到困扰,欢迎您构建自己的检查(实际上并不难,使用 ast
模块),或者分叉现有的 linter 并修改规则以适应口味。