Python入门指南之代码注释的三种写法详解
作者:星河耀银海

一、开篇:好代码需要好注释
在上一篇文章中,我们写出了第一行Python代码。今天我们要聊一个看似简单、但很多程序员做了很多年都没做好的话题:代码注释。
注释是写在代码里、但不被Python执行的一段文字。它的作用是给读代码的人(包括未来的你自己)解释代码的含义、逻辑和注意事项。
你可能觉得"我写的代码我自己能看懂,不需要注释"。相信我,三个月后回来看你今天写的代码,如果没有注释,你大概率会对着屏幕发呆:“这代码到底是谁写的?”——是你自己写的,但你已经忘了当时的思路。
一个编程高手的标志之一,就是能写出恰到好处的注释。不是越多越好,也不是越少越好,而是"刚好解释清楚为什么这样写"。
二、Python的三种注释方式
Python提供了三种写注释的方式,每种都有自己的用途。
2.1 单行注释:井号
这是最常用的注释方式。以 # 开头,# 之后直到行尾的所有内容都是注释。
# 这是一个单行注释
print('Hello, World!') # 这行打印一句话,这也是注释
# 下面这行代码计算1到100的和
total = 0
for i in range(1, 101):
total += i # 累加每一个数字
print(total) # 输出结果:5050
单行注释也可以用来临时禁用某一行代码(调试时特别常用):
print('这条会执行')
# print('这条不会执行,因为被注释掉了')
print('这条也会执行')
绝大多数IDE中,选中几行代码然后按 Ctrl + /(Mac:Cmd + /)可以快速注释/取消注释。
2.2 多行注释:三个引号
用三个单引号 ''' 或三个双引号 """ 包裹起来的内容,可以作为多行注释。
''' 这是一个多行注释 可以跨越多行 Python解释器会忽略这些内容 ''' """ 这也是一个多行注释 用双引号也是一样的效果 可以写很多行 """
技术细节:三个引号在Python中实际上创建了一个字符串对象,只是这个字符串没有被赋值给任何变量,所以Python创建了它之后马上丢弃。因此严格来说这不是"注释",而是一个"被丢弃的字符串字面量"。但在实际使用中,大家都把它当作多行注释来用。
三种引号的使用场景:
# 函数的文档字符串——这是最正式的用法
def calculate_area(length, width):
"""
计算矩形的面积。
参数:
length (float): 矩形的长度
width (float): 矩形的宽度
返回:
float: 矩形的面积
"""
return length * width
# 代码顶部的模块说明
'''
模块名:用户管理
功能:处理用户的注册、登录、信息修改等操作
作者:张三
日期:2025-05-30
版本:v1.0
'''
# 临时注释掉一大段代码
'''
print('这段代码暂时不需要执行')
print('先用三个引号把它包起来')
print('等需要的时候再解开')
'''
2.3 文档字符串(docstring)
文档字符串是Python中的特殊注释形式,它用 """...""" 包裹,写在函数、类、模块的第一行。它和普通注释最大的区别是:文档字符串可以被程序读取。
def greet(name, greeting='你好'):
"""向指定的人打招呼。
Args:
name: 被问候的人的名字
greeting: 问候语,默认为"你好"
Returns:
str: 完整的问候语字符串
Examples:
>>> greet('小明')
'你好,小明!'
>>> greet('小红', '嗨')
'嗨,小红!'
"""
return f'{greeting},{name}!'
# 文档字符串可以通过__doc__属性被程序访问
print(greet.__doc__)
# 输出上面写的整个文档
# 也可以用help()函数查看
help(greet)
# 输出格式化的文档
养成写文档字符串的好习惯。对于你自己定义的函数和类,花一分钟写一个简短的文档字符串,几个月后你会感谢现在的自己。
三、什么时候该写注释
3.1 必须写注释的场景
场景一:解释"为什么",而不是"是什么"
没有意义的注释(只是在重复代码):
x = x + 1 # 将x加1
有价值的注释(解释了原因):
x = x + 1 # 补偿索引偏移,因为用户输入的序号从1开始而不是0
场景二:非显而易见的算法或逻辑
# 使用埃拉托斯特尼筛法找出所有质数
def sieve_of_eratosthenes(n):
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
# 只需要检查到sqrt(n),因为如果n是合数,
# 它必定有一个因子小于等于sqrt(n)
for i in range(2, int(n ** 0.5) + 1):
if is_prime[i]:
for j in range(i * i, n + 1, i):
is_prime[j] = False
return [i for i in range(2, n + 1) if is_prime[i]]
场景三:带有特殊限制或注意事项的代码
# 注意:这个函数假设输入列表已按升序排列
# 如果列表未排序,返回的结果将是错误的
def binary_search(sorted_list, target):
# ... 二分查找的实现
场景四:解决特定bug的代码
# 在Windows上,文件路径中的反斜杠需要转义
# 使用os.path.join可以避免平台差异
import os
file_path = os.path.join('data', 'users', 'info.csv')
场景五:TODO和FIXME标记
# TODO: 这里的错误处理需要完善,目前只在理想情况下工作 # FIXME: 当用户名为空时会崩溃,需要添加空值检查 # HACK: 这是一个临时方案,等后端接口好了之后要重构
3.2 不需要写注释的场景
不需要注释一:代码本身已经足够清晰
# 不需要注释 name = '小明' # 设置名字为小明 age = 20 # 设置年龄为20 # 上面的注释完全是废话,代码已经说得很清楚了
不需要注释二:可以从良好命名中直接看出的逻辑
# 不需要注释——函数名和变量名已经说明了一切
def calculate_average_score(scores):
total = sum(scores)
count = len(scores)
return total / count
不需要注释三:可以抽取为函数的复杂逻辑
# ❌ 一大段需要注释的复杂代码
def process_order(order):
# 首先验证订单状态,必须是"待发货"
# 然后检查库存是否充足
# 如果库存足够,扣减库存
# 最后更新订单状态为"已发货"
# ... 20行代码
pass
# ✅ 拆分为小函数,函数名本身就是最好的注释
def process_order(order):
validate_order(order)
check_inventory(order)
deduct_inventory(order)
update_order_status(order, '已发货')
四、注释的黄金法则
4.1 注释解释"为什么",代码说明"是什么"
# ❌ 坏注释:重复代码
# 遍历员工列表
for employee in employees:
# 计算工资
salary = employee.hours * employee.hourly_rate
# 打印工资
print(salary)
# ✅ 好注释:解释背后的意图
for employee in employees:
salary = employee.hours * employee.hourly_rate
# 根据公司政策,加班时间按1.5倍计算
if employee.hours > 40:
overtime_hours = employee.hours - 40
salary += overtime_hours * employee.hourly_rate * 0.5
print(salary)
4.2 注释要保持更新
最危险的注释是过时的注释——代码已经改了,但注释没有同步更新。
# ❌ 危险的过时注释
def calculate_tax(income):
# 使用2018年的税率(实际上2025年已经改了!)
if income < 5000:
return 0
elif income < 8000:
return income * 0.03
# ...
# ✅ 更好的做法:用清楚的代码代替注释
# 税率表直接来自数据,代码本身说明了逻辑
TAX_BRACKETS_2025 = [
(0, 5000, 0),
(5000, 8000, 0.03),
(8000, 17000, 0.10),
# ...
]
def calculate_tax(income):
for lower, upper, rate in TAX_BRACKETS_2025:
if lower <= income < upper:
return (income - lower) * rate
4.3 注释用英文还是中文
这是中文开发者经常纠结的问题。我的建议:
- 个人项目 / 学习笔记:用中文,表达更顺畅
- 团队项目 / 开源项目:遵循项目已有的规范。通常建议用英文(方便国际协作)
- docstring:如果项目可能开源,建议中英文都写,或者写英文
# 个人学习项目——中文注释完全OK
def binary_search(arr, target):
"""二分查找算法"""
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid # 找到了
elif arr[mid] < target:
left = mid + 1 # 目标在右半部分
else:
right = mid - 1 # 目标在左半部分
return -1 # 没找到
五、实战:给一段代码写注释
让我们通过一个实际例子,看看有注释和没有注释的代码有什么区别。
5.1 没有注释的版本
def f(d, p):
r = []
for k, v in d.items():
if p(v):
r.append(k)
return r
data = {'a': 85, 'b': 42, 'c': 96, 'd': 58, 'e': 73}
print(f(data, lambda x: x >= 60))
你能一眼看出这个程序在做什么吗?可能需要花点时间。
5.2 加了注释的版本
"""
学生成绩筛选程序
功能:从学生成绩字典中筛选出及格(>=60分)的学生名单
"""
def filter_by_criteria(data_dict, check_function):
"""
根据指定的筛选条件,从字典中筛选出符合条件的键。
参数:
data_dict (dict): 待筛选的字典,键为学生名,值为成绩
check_function (callable): 筛选函数,接受一个值,返回True/False
返回:
list: 符合条件的键(学生名)列表
示例:
>>> scores = {'小明': 85, '小红': 42}
>>> filter_by_criteria(scores, lambda x: x >= 60)
['小明']
"""
passed_keys = [] # 存储符合条件的学生名
for key, value in data_dict.items():
if check_function(value):
passed_keys.append(key) # 该学生成绩符合条件,加入结果
return passed_keys
# 学生成绩数据
student_scores = {
'小明': 85,
'小红': 42,
'小刚': 96,
'小丽': 58,
'小华': 73
}
# 筛选条件:成绩大于等于60分(及格线)
def is_passing(score):
return score >= 60
# 执行筛选并输出结果
passing_students = filter_by_criteria(student_scores, is_passing)
print(f'及格的学生有:{passing_students}')
print(f'及格人数:{len(passing_students)}人')
print(f'不及格人数:{len(student_scores) - len(passing_students)}人')
现在代码的意思非常清楚了。虽然代码行数变多了,但可读性提升了不止一个档次。好的命名加上适当的注释,让这段代码即使给一个完全没见过的开发者看,也能立刻理解它在做什么。
六、各种语言的注释对比
了解其他语言的注释方式,有助于你理解Python注释的特点:
| 语言 | 单行注释 | 多行注释 |
|---|---|---|
| Python | # 注释 | '''注释''' 或 """注释""" |
| C/C++/Java | // 注释 | /* 注释 */ |
| JavaScript | // 注释 | /* 注释 */ |
| SQL | -- 注释 | /* 注释 */ |
| Bash/Shell | # 注释 | : '注释' |
| HTML | N/A | <!-- 注释 --> |
Python不像C/Java那样有专门的多行注释语法,而是巧妙地将字符串字面量复用作多行注释。这个设计体现了Python的极简哲学——少即是多。
七、注释在调试中的妙用
7.1 逐段排查bug
当程序出问题时,注释是最高效的调试工具之一:
def complex_calculation(data):
# 第一步:数据清洗
cleaned_data = clean_data(data)
print(f'清洗后数据条数:{len(cleaned_data)}')
# 第二步:数据转换(怀疑这里有bug,先注释掉后面,只看前面的输出)
# transformed_data = transform_data(cleaned_data)
# print(f'转换后数据条数:{len(transformed_data)}')
# 第三步:计算
# result = calculate(transformed_data)
# return result
# 暂时返回None,等排查完bug再恢复
return None
7.2 用注释做"版本控制"
在学习和实验阶段,可以保留多种写法做对比:
# 写法一:使用列表推导式
# squared = [x**2 for x in range(10)]
# 写法二:使用map函数
# squared = list(map(lambda x: x**2, range(10)))
# 写法三:传统for循环——当前采用这种写法,最易读
squared = []
for x in range(10):
squared.append(x ** 2)
print(squared)
八、本篇小结
注释是写给人的,不是写给机器的。机器根本看不懂你的注释,但三个月后的你自己会感激今天的注释。
核心要点回顾:
- 三种注释方式:
#单行、'''/"""多行、docstring文档字符串 - 注释解释"为什么",不要只重复"是什么"
- 保持注释和代码同步,过时的注释比没有注释更危险
- 好的命名是注释的替代品——当代码自己就能说清楚意思时,不需要额外注释
- 关键逻辑必须注释:算法原理、业务规则、特殊限制、已知问题
写注释是一种代码素养。它不是额外的负担,而是编码过程中自然的一部分。从今天开始,每写一段代码,养成问自己"别人读到这里能明白吗"的习惯。下一篇我们将进入Python的基础语法——缩进规则和代码块规范。
以上就是Python入门指南之代码注释的三种写法详解的详细内容,更多关于Python代码注释的资料请关注脚本之家其它相关文章!
