
Ruff 将模块级 docstring 视为执行语句,因此若其位于 from __future__ 导入之后(即使之前无代码),后续普通导入就会触发 E402 错误;正确做法是将 docstring 置于文件最顶端(首行),早于所有导入(含 __future__),才能被 Python 正确识别为模块文档。
ruff 将模块级 docstring 视为执行语句,因此若其位于 `from __future__` 导入之后(即使之前无代码),后续普通导入就会触发 e402 错误;正确做法是将 docstring 置于文件最顶端(首行),早于所有导入(含 `__future__`),才能被 python 正确识别为模块文档。
在 Python 中,模块级文档字符串(module docstring)只有在文件开头、且紧随可选编码声明或空白行之后、位于任何可执行语句(包括 import)之前时,才会被自动赋值给 __doc__。一旦它出现在 from __future__ 或其他导入语句之后,Python 解释器就将其视为普通字符串字面量,而非文档字符串——这意味着 __doc__ 将为 None,工具链(如 Sphinx、IDE 文档提示、help())也无法提取该信息。
Ruff 的 E402 Module level import not at top of file 报错看似针对导入位置,实则是一个关键提示:你当前的 docstring 并未生效。因为从语法角度看,"""...""" 是一个表达式语句(expression statement),与 x = 1 或 print() 同类。Ruff 严格遵循 PEP 257 和 Python 解析规则,要求所有 import 必须出现在所有执行语句之前——而 docstring 若不在顶部,就属于“破坏顺序”的执行语句。
✅ 正确写法(推荐,符合规范且兼容所有工具):
"""Module level docstring. This is the official documentation for this module. It appears before ANY imports — including __future__. """ from __future__ import annotations from datetime import datetime as DateTime print(DateTime.today())
此时运行:
$ python3 -c "import t; print(t.__doc__[:20])" Module level docstring.
❌ 错误写法(docstring 失效,Ruff 报错,flake8 不报但行为不一致):
from __future__ import annotations """ This is NOT a module docstring — it's just a string literal. """ from datetime import datetime as DateTime # ← E402 triggered here
⚠️ 注意事项:
__future__导入虽允许在 docstring 之后(CPython 允许),但docstring 必须在__future__之前才能被识别;这是语言规范,非 Ruff 特有约束。- 不要通过
# noqa: E402全局抑制该错误——它会掩盖真实问题(如意外在函数内导入),且违背 PEP 257。- 若项目存在大量历史文件,建议使用自动化脚本批量修复:先提取现有 docstring(若存在且非注释),再移动至文件首行,保留原有缩进与格式。
- Ruff 的行为比 flake8 更严格,但更贴近 Python 运行时语义;这种“提前预警”恰恰提升了代码的可维护性与工具链兼容性。
总结:这不是 Ruff 需要“修正”的行为,而是它在帮你发现一个长期被忽略的语义缺陷。将 docstring 放回文件顶端,既是解决 E402 的唯一合规方式,也是确保文档真正可用的根本保障。

















