Python单行注释必须以#开头且后跟至少一个空格,禁用末尾无空格写法;三引号非注释而是字符串字面量,多行说明应使用连续#;文档字符串需严格置于模块/函数/类首行且缩进正确;类型提示与docstring内容应互补而非重复。

Python单行注释用#,别写在代码同一行末尾还带空格问题
单行注释必须以#开头,后面至少一个空格——这是PEP 8明确要求的。很多人随手写成print("hi")#注释,看着能运行,但工具链(如pylint、black)会报C0116或格式警告,CI里可能直接失败。
-
#后不加空格:被flake8标为E261错误 - 写在语句同一行末尾:可读性差,尤其带字符串或括号时容易误判注释范围
- 正确写法是独占一行,或在语句上方空一行再写(函数/逻辑块前)
示例:
# ✅ 推荐:独立一行,有空格<br>user_id = get_current_user() # ✅ 也可放行尾,但必须有空格<br><br># ❌ 不推荐<br>user_id=get_current_user()#注释没空格<br>if x > 0: # 这里缩进和冒号后紧贴,易读性低
Python多行注释不是'''或""",那是字符串字面量
新手常把三引号当成“多行注释”,其实它只是未赋值的字符串——会被解析、占用内存、出现在__doc__里(如果在模块/函数/类开头)。真要写临时屏蔽多行代码,得用编辑器快捷键(如Ctrl+/)或逐行加#。
- 三引号内容若在函数定义第一行,会被自动设为
__doc__,影响help()和IDE提示 - 放在非文档位置(比如循环中间),会生成无用对象,CPython虽会优化掉,但PyPy或某些静态分析工具仍可能报
W0105(unused expression) - 真正需要多行说明时,拆成多个
#行更安全、更符合工具链预期
示例:
# ✅ 多行说明(非文档)<br># - 参数校验逻辑较复杂<br># - 需兼容旧版API返回结构<br># - 后续考虑抽成独立函数<br>if not data or "items" not in data:<br> return []
立即学习“Python免费学习笔记(深入)”;
函数/模块文档字符串用""",但位置和缩进不能错
文档字符串(docstring)是唯一被Python官方认可的“代码内文档”,但只在特定位置生效:模块最顶部、函数def下一行、类class下一行,且必须顶格或与代码同级缩进(不能比def多缩进)。
- 写在函数体内部任意位置(比如
if块里):不会被help()识别,pydoc也查不到 - 缩进多了一层(比如4空格函数体里写了8空格的
"""):会被当成普通字符串,__doc__为None - 换行后第二行没缩进到正文起始列:部分工具(如Sphinx)解析失败,生成文档时丢内容
示例:
def parse_config(path):<br> """解析配置文件,支持JSON/YAML格式。<br><br> Args:<br> path (str): 配置文件路径<br><br> Returns:<br> dict: 解析后的配置字典<br> """<br> ...
类型提示+docstring组合用,别让注释和类型信息重复打架
Python 3.7+有了typing和函数注解,很多信息(比如参数类型、返回值)不该再塞进docstring里重复写。否则类型检查工具(如mypy)和文档生成器(如Sphinx autodoc)会各自取信不同来源,导致矛盾。
- 参数类型已用
def func(x: int) -> str:声明,docstring里就别再写Args: x (int): ... - 想补充行为细节(比如“x为负数时触发降级逻辑”)可以写,但避免和类型系统冲突
- 用
typing.Union或Optional时,docstring里写None含义比写NoneType更自然
真实踩坑点:有人在docstring里写Returns: User | None,但代码注解是-> Optional[User],mypy不报错,sphinx-autodoc却渲染成两套返回说明,下游开发者看懵。
实际写的时候,最容易被忽略的是:docstring的缩进层级和空行规则,比语法更影响协作体验。编辑器不一定高亮报错,但团队里有人用VS Code + Pylance,有人用PyCharm + mypy,差一个空格,help()输出就变样。










