Python3 注释编写完全指南:从基础规范到高效实践
Python3 注释编写完全指南:从基础规范到高效实践
注释这事儿,说大不大,说小不小。写好了帮你省三个月后的记忆,写砸了比不写还坑人。这篇把注释的规矩、套路和坑一次说清楚。
WEB项目地址:演示地址
安卓APP下载地址:演示地址
① 注释的核心价值与适用场景解析
注释到底是写给谁看的?
写给你的队友看,也写给三个月后的自己看。
代码是写给计算机执行的,但代码也是给人读的。一个函数干了什么事、参数有什么约束、返回值什么格式——这些信息光靠看代码不一定能一眼看出来。注释就是用来补上这段“代码没写明白”的信息。
什么时候该写注释?
- 复杂的业务逻辑:比如订单金额的计算规则、折扣叠加的顺序
- 非常规的实现方式:比如“这里故意不用算法 A 而用算法 B,因为 A 在大数据量下会 OOM”
- 对外暴露的 API / 公共函数:别人要调你的代码,得知道怎么用
- 临时的处理方案:比如“TODO: 等后端接口上线后替换这里的 mock 数据”
什么时候不用写注释?
代码本身就能说清楚的事,别重复一遍。比如i += 1旁边写“i 加 1”——这就是废话。
② 单行注释的正确写法与快捷操作
Python 的单行注释用井号#开头。从#开始到这一行结束的所有内容,解释器都忽略。
# 计算订单总价,包含税费和运费total=subtotal*1.08+shipping_fee两条硬规矩:
规矩一:#后面跟一个空格再写文字。这是 PEP 8 官方推荐的写法,几乎所有 Python 项目都遵守。
# 好的写法# 坏的写法(井号后面没空格)规矩二:注释和代码至少空两个空格。如果是写在代码行末尾的注释,#前面至少空两格。
price=99.9# 原价,单位美元discount_rate=0.2# 折扣率,目前全场八折快捷操作:
大多数编辑器里,选中多行按Ctrl + /(Windows/Linux)或Cmd + /(Mac)可以批量加/取消单行注释。这个快捷键平时用得最多——调试时临时屏蔽一段代码,一秒钟搞定。
③ 多行注释与文档字符串的区别用法
很多教材说 Python 的多行注释是用三个引号"""或'''括起来——这个说法其实不准确。
三个引号包裹的字符串如果没赋值给任何变量,解释器确实会忽略它,效果上像注释。但它的本质是字符串字面量,不是真正的注释语法。
""" 这是一段被三个引号括起来的文字。 解释器会把它当作一个字符串常量, 但不赋值的话就直接丢弃了。 """真正靠谱的多行注释方式:
每行前面都加#。这是 PEP 8 推荐的做法,也是绝大多数 Python 项目的实际写法。
# 这里实现了一个简单的缓存淘汰策略。# 当缓存大小超过 max_size 时,# 移除最早加入的那个条目。defevict_cache(cache,max_size):...什么时候用三个引号?
用三个引号写正式的文档字符串(docstring),专门给函数、类、模块写说明文档用的。它不是注释,是文档。下面第④节细说。
④ 函数与类文档字符串的标准结构
文档字符串(docstring)是写在函数或类定义下面的第一行,用三个双引号括起来。它和注释最大的区别是:注释是给人看的,docstring 可以被程序读取。
defcalculate_discount(original_price,member_level):"""根据会员等级计算折扣后的价格。 Args: original_price: 原价,单位元,正数。 member_level: 会员等级,'gold' / 'silver' / 'bronze'。 Returns: 折扣后的价格,单位元。如果原价无效则返回 -1。 Raises: ValueError: 会员等级不在支持范围内时抛出。 """iforiginal_price<0:return-1# ... 具体实现标准结构包含这几块:
- 第一行:一句话说清楚函数是干嘛的
- 空一行
Args::列出每个参数,说明类型和含义Returns::说明返回值,包括什么情况返回什么Raises:(可选):什么情况会抛什么异常
用help()直接看:
在交互式环境里执行help(calculate_discount),上面写的 docstring 会直接打印出来。这才是 docstring 的真正价值——不用打开源码就能知道怎么用。
常见的 docstring 风格:
- Google 风格:上面示例那种,可读性最好,推荐新手用
- NumPy/SciPy 风格:更详细,参数描述独占一行,适合科学计算项目
- Sphinx(reST)风格:用
:param name:这种格式,和 Sphinx 文档生成工具配合用
新手优先用 Google 风格,够用、好读。
⑤ 代码逻辑注释的编写最佳实践
写逻辑注释的核心原则就一条:解释“为什么”,而不是“是什么”。
# 差评:代码已经说明了一切# 将 total 乘以 0.9total=total*0.9# 好评:说明背后的业务原因# VIP 用户享受 9 折优惠,这个规则 2023 年 6 月上线total=total*0.9对复杂条件判断加注释:
# 只有已登录、且账户余额大于 100 元、且最近 30 天有消费记录的用户# 才发放优惠券。这是运营部门 2025 年 Q1 的新规。ifuser.is_authenticatedanduser.balance>100anduser.last_purchase_days<30:grant_coupon(user)这种注释的价值在于:三个月后维护这段代码的人(可能是你自己)一看就知道为什么有这些条件,而不是小心翼翼地猜“动了这个会不会炸”。
对“非常规写法”加注释:
# 这里用 while 循环而不是 for,是因为列表在遍历过程中会动态变长,# for 循环无法正确处理动态变化的长度。idx=0whileidx<len(queue):process(queue[idx])idx+=1⑥ 避免无效注释与过度注释的技巧
无效注释长什么样?
x=x+1# x 增加 1# 初始化计数器counter=0这种注释纯属凑数。变量名本身就说明了一切。删了它,代码更清爽。
过度注释长什么样?
# 第一步:打开文件file=open('data.txt')# 第二步:读取所有行lines=file.readlines()# 第三步:遍历每一行forlineinlines:# 第四步:去掉末尾换行符line=line.strip()# 第五步:打印这一行print(line)把“步骤”这种流程性的东西当注释,每行代码配一句解释——纯属噪音。真正有用的不是“做什么”,而是“为什么这么做”。
判断一个注释该不该留,问自己三个问题:
- 删掉这个注释,代码还能不能一眼看懂?
- 这个注释补充了代码没有表达的信息吗?
- 如果我不写这个注释,维护者会误解这段代码吗?
三个问题都回答“是”,才值得写注释。
⑦ 利用注释进行临时调试的方法
注释在调试的时候特别有用——把代码“关掉”比删掉安全。
屏蔽某一段代码:
选中要屏蔽的代码,按Ctrl + /(Mac 是Cmd + /),整段变成注释。想恢复再按一次取消注释。
# 发邮件通知用户# send_notification_email(user, order)# 记录日志到数据库# log_to_database(event)用注释做“开关”:
有时候你想快速切换两种实现,可以这样:
# 正式环境用真实 APIresult=call_real_api(params)# 测试环境用模拟数据(上面那行注释掉,下面这行取消注释)# result = mock_response(params)用TODO标记待办:
这不算严格意义的注释,但实际工作中每天都在用:
defprocess_order(order):# TODO: 等支付接口稳定后,加一个重试逻辑# FIXME: 这里的税率写死了 0.08,需要改成从配置读取# BUG: 订单金额为 0 时这里会除零,下个版本修...多数编辑器会把TODO和FIXME高亮显示,一眼就能看到哪些地方还没做完。
⑧ 主流编辑器注释快捷键大全
| 编辑器 / IDE | 注释/取消注释(单行) | 块注释 |
|---|---|---|
| VS Code | Ctrl + /(Win) /Cmd + /(Mac) | 同上 |
| PyCharm | Ctrl + /(Win) /Cmd + /(Mac) | Ctrl + Shift + /(Win) /Cmd + Shift + /(Mac) |
| Sublime Text | Ctrl + /(Win) /Cmd + /(Mac) | Ctrl + Shift + /(Win) /Cmd + Shift + /(Mac) |
| Vim | gc在 Visual 模式下 | 用插件或:s/^/#/ |
| Jupyter Notebook | Ctrl + /(Win) /Cmd + /(Mac) | 同上 |
| IDLE(自带) | Alt + 3注释 /Alt + 4取消注释 | 无快捷键,手动加# |
记住最通用的那组就行:Ctrl + /(或Cmd + /)通吃 90% 的编辑器。
⑨ 团队协作中的注释风格统一规范
一个人写代码怎么都行,一群人写代码必须统一规矩。以下是实际团队里最实用的几条:
1. 注释用英文还是中文?
看团队情况。全员英文能力过关就用英文——兼容性最好,GitHub 开源项目也方便。国内团队用中文完全没问题,关键是统一,不要中英混用。
2. 用#加空格的写法
前面说了,#后面跟一个空格。所有人统一。
3. docstring 统一风格
定一种 docstring 风格,全团队用同一种。新手团队建议直接定 Google 风格,上手快。
4. 文件头注释
有些团队要求在文件开头写版权、作者、创建日期等信息:
#!/usr/bin/env python3# -*- coding: utf-8 -*-# Copyright (c) 2026 YourCompany. All rights reserved.实际上现在 Python 3 默认 UTF-8 编码,第二行# -*- coding: utf-8 -*-基本不需要了。文件头要不要写、写什么、怎么写,按团队自己的规矩来。
5. 用 linter 自动检查
在项目里配置flake8或pylint,把注释规范加进去。不符合规范的代码提交时会报警告——省得 code review 时候吵。
⑩ 常见注释误区与修正案例演示
误区一:注释和代码不同步
代码改了,注释没改——这是最坑的情况。注释说“返回用户列表”,实际上返回的是字典。看注释的人被带沟里。
修正:修改代码的同时,必须同步更新注释。做不到就不要写注释,错误注释比没注释更可怕。
误区二:把注释当草稿纸
# 这个函数写得比较烂,后面再优化# 感觉这里可以加个缓存,但我还不确定# 这个地方纠结了好久这种情绪化的自言自语不该出现在正式代码里。要么把思路理清楚再写,要么删掉这些废话。
误区三:注释缩写过多
# init db conn, retry if fail“db” 还算常见,“init”“conn”“retry” 也还行。但有些团队内部用的生僻缩写,新人完全看不懂。注释是为了让人读懂,不是加密。
误区四:docstring 写得太简略
defparse_config(filepath):"""解析配置文件。"""这等于没写。至少要说清楚:配置文件是什么格式、解析失败怎么办、返回什么结构。
一组前后对比:
修改前:
defget_data(id):# get data by idres=requests.get(url+id)# parse jsondata=res.json()# return datareturndata['result']修改后:
defget_user_profile(user_id):"""从用户中心 API 获取用户基本信息。 Args: user_id: 用户的唯一标识 ID,字符串格式。 Returns: 包含用户昵称、头像 URL、注册时间的字典。 如果用户不存在,API 返回 404,本函数返回 None。 Raises: requests.RequestException: 网络请求失败时抛出。 """api_url=f"{USER_API_BASE}/profile/{user_id}"response=requests.get(api_url)ifresponse.status_code==404:returnNoneresponse.raise_for_status()payload=response.json()returnpayload.get('result')修改后的代码:变量名自解释、docstring 完整、逻辑清晰、基本不需要额外的行内注释。这才是注释该有的样子——该写的地方写透,不该写的地方一句废话都没有。