当前位置: 首页 > news >正文

Python入门:Python代码注释的三种写法详解

Python入门:Python代码注释的三种写法详解

一、开篇:好代码需要好注释

在上一篇文章中,我们写出了第一行Python代码。今天我们要聊一个看似简单、但很多程序员做了很多年都没做好的话题:代码注释

📝 注释是写在代码里、但不被Python执行的一段文字。它的作用是给读代码的人(包括未来的你自己)解释代码的含义、逻辑和注意事项。

你可能觉得"我写的代码我自己能看懂,不需要注释"。相信我,三个月后回来看你今天写的代码,如果没有注释,你大概率会对着屏幕发呆:“这代码到底是谁写的?”——是你自己写的,但你已经忘了当时的思路。

💡 一个编程高手的标志之一,就是能写出恰到好处的注释。不是越多越好,也不是越少越好,而是"刚好解释清楚为什么这样写"。

二、Python的三种注释方式

Python提供了三种写注释的方式,每种都有自己的用途。

2.1 单行注释:井号

这是最常用的注释方式。以#开头,#之后直到行尾的所有内容都是注释。

# 这是一个单行注释print('Hello, World!')# 这行打印一句话,这也是注释# 下面这行代码计算1到100的和total=0foriinrange(1,101):total+=i# 累加每一个数字print(total)# 输出结果:5050

单行注释也可以用来临时禁用某一行代码(调试时特别常用):

print('这条会执行')# print('这条不会执行,因为被注释掉了')print('这条也会执行')

⌨️ 绝大多数IDE中,选中几行代码然后按Ctrl + /(Mac:Cmd + /)可以快速注释/取消注释。

2.2 多行注释:三个引号

用三个单引号'''或三个双引号"""包裹起来的内容,可以作为多行注释。

''' 这是一个多行注释 可以跨越多行 Python解释器会忽略这些内容 '''""" 这也是一个多行注释 用双引号也是一样的效果 可以写很多行 """

⚠️ 技术细节:三个引号在Python中实际上创建了一个字符串对象,只是这个字符串没有被赋值给任何变量,所以Python创建了它之后马上丢弃。因此严格来说这不是"注释",而是一个"被丢弃的字符串字面量"。但在实际使用中,大家都把它当作多行注释来用。

三种引号的使用场景:

# 函数的文档字符串——这是最正式的用法defcalculate_area(length,width):""" 计算矩形的面积。 参数: length (float): 矩形的长度 width (float): 矩形的宽度 返回: float: 矩形的面积 """returnlength*width# 代码顶部的模块说明''' 模块名:用户管理 功能:处理用户的注册、登录、信息修改等操作 作者:张三 日期:2025-05-30 版本:v1.0 '''# 临时注释掉一大段代码''' print('这段代码暂时不需要执行') print('先用三个引号把它包起来') print('等需要的时候再解开') '''

2.3 文档字符串(docstring)

文档字符串是Python中的特殊注释形式,它用"""..."""包裹,写在函数、类、模块的第一行。它和普通注释最大的区别是:文档字符串可以被程序读取

defgreet(name,greeting='你好'):"""向指定的人打招呼。 Args: name: 被问候的人的名字 greeting: 问候语,默认为"你好" Returns: str: 完整的问候语字符串 Examples: >>> greet('小明') '你好,小明!' >>> greet('小红', '嗨') '嗨,小红!' """returnf'{greeting}{name}!'# 文档字符串可以通过__doc__属性被程序访问print(greet.__doc__)# 输出上面写的整个文档# 也可以用help()函数查看help(greet)# 输出格式化的文档

💡 养成写文档字符串的好习惯。对于你自己定义的函数和类,花一分钟写一个简短的文档字符串,几个月后你会感谢现在的自己。

三、什么时候该写注释

3.1 必须写注释的场景

场景一:解释"为什么",而不是"是什么"

❌ 没有意义的注释(只是在重复代码):

x=x+1# 将x加1

✅ 有价值的注释(解释了原因):

x=x+1# 补偿索引偏移,因为用户输入的序号从1开始而不是0

场景二:非显而易见的算法或逻辑

# 使用埃拉托斯特尼筛法找出所有质数defsieve_of_eratosthenes(n):is_prime=[True]*(n+1)is_prime[0]=is_prime[1]=False# 只需要检查到sqrt(n),因为如果n是合数,# 它必定有一个因子小于等于sqrt(n)foriinrange(2,int(n**0.5)+1):ifis_prime[i]:forjinrange(i*i,n+1,i):is_prime[j]=Falsereturn[iforiinrange(2,n+1)ifis_prime[i]]

场景三:带有特殊限制或注意事项的代码

# 注意:这个函数假设输入列表已按升序排列# 如果列表未排序,返回的结果将是错误的defbinary_search(sorted_list,target):# ... 二分查找的实现

场景四:解决特定bug的代码

# 在Windows上,文件路径中的反斜杠需要转义# 使用os.path.join可以避免平台差异importos file_path=os.path.join('data','users','info.csv')

场景五:TODO和FIXME标记

# TODO: 这里的错误处理需要完善,目前只在理想情况下工作# FIXME: 当用户名为空时会崩溃,需要添加空值检查# HACK: 这是一个临时方案,等后端接口好了之后要重构

3.2 不需要写注释的场景

不需要注释一:代码本身已经足够清晰

# 不需要注释name='小明'# 设置名字为小明age=20# 设置年龄为20# 上面的注释完全是废话,代码已经说得很清楚了

不需要注释二:可以从良好命名中直接看出的逻辑

# 不需要注释——函数名和变量名已经说明了一切defcalculate_average_score(scores):total=sum(scores)count=len(scores)returntotal/count

不需要注释三:可以抽取为函数的复杂逻辑

# ❌ 一大段需要注释的复杂代码defprocess_order(order):# 首先验证订单状态,必须是"待发货"# 然后检查库存是否充足# 如果库存足够,扣减库存# 最后更新订单状态为"已发货"# ... 20行代码pass# ✅ 拆分为小函数,函数名本身就是最好的注释defprocess_order(order):validate_order(order)check_inventory(order)deduct_inventory(order)update_order_status(order,'已发货')

四、注释的黄金法则

4.1 注释解释"为什么",代码说明"是什么"

# ❌ 坏注释:重复代码# 遍历员工列表foremployeeinemployees:# 计算工资salary=employee.hours*employee.hourly_rate# 打印工资print(salary)# ✅ 好注释:解释背后的意图foremployeeinemployees:salary=employee.hours*employee.hourly_rate# 根据公司政策,加班时间按1.5倍计算ifemployee.hours>40:overtime_hours=employee.hours-40salary+=overtime_hours*employee.hourly_rate*0.5print(salary)

4.2 注释要保持更新

⚠️ 最危险的注释是过时的注释——代码已经改了,但注释没有同步更新。

# ❌ 危险的过时注释defcalculate_tax(income):# 使用2018年的税率(实际上2025年已经改了!)ifincome<5000:return0elifincome<8000:returnincome*0.03# ...# ✅ 更好的做法:用清楚的代码代替注释# 税率表直接来自数据,代码本身说明了逻辑TAX_BRACKETS_2025=[(0,5000,0),(5000,8000,0.03),(8000,17000,0.10),# ...]defcalculate_tax(income):forlower,upper,rateinTAX_BRACKETS_2025:iflower<=income<upper:return(income-lower)*rate

4.3 注释用英文还是中文

这是中文开发者经常纠结的问题。我的建议:

  • 个人项目 / 学习笔记:用中文,表达更顺畅
  • 团队项目 / 开源项目:遵循项目已有的规范。通常建议用英文(方便国际协作)
  • docstring:如果项目可能开源,建议中英文都写,或者写英文
# 个人学习项目——中文注释完全OKdefbinary_search(arr,target):"""二分查找算法"""left,right=0,len(arr)-1whileleft<=right:mid=(left+right)//2ifarr[mid]==target:returnmid# 找到了elifarr[mid]<target:left=mid+1# 目标在右半部分else:right=mid-1# 目标在左半部分return-1# 没找到

五、实战:给一段代码写注释

让我们通过一个实际例子,看看有注释和没有注释的代码有什么区别。

5.1 没有注释的版本

deff(d,p):r=[]fork,vind.items():ifp(v):r.append(k)returnr data={'a':85,'b':42,'c':96,'d':58,'e':73}print(f(data,lambdax:x>=60))

你能一眼看出这个程序在做什么吗?可能需要花点时间。

5.2 加了注释的版本

""" 学生成绩筛选程序 功能:从学生成绩字典中筛选出及格(>=60分)的学生名单 """deffilter_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=[]# 存储符合条件的学生名forkey,valueindata_dict.items():ifcheck_function(value):passed_keys.append(key)# 该学生成绩符合条件,加入结果returnpassed_keys# 学生成绩数据student_scores={'小明':85,'小红':42,'小刚':96,'小丽':58,'小华':73}# 筛选条件:成绩大于等于60分(及格线)defis_passing(score):returnscore>=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# 注释: '注释'
HTMLN/A<!-- 注释 -->

Python不像C/Java那样有专门的多行注释语法,而是巧妙地将字符串字面量复用作多行注释。这个设计体现了Python的极简哲学——少即是多。

七、注释在调试中的妙用

7.1 逐段排查bug

当程序出问题时,注释是最高效的调试工具之一:

defcomplex_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再恢复returnNone

7.2 用注释做"版本控制"

在学习和实验阶段,可以保留多种写法做对比:

# 写法一:使用列表推导式# squared = [x**2 for x in range(10)]# 写法二:使用map函数# squared = list(map(lambda x: x**2, range(10)))# 写法三:传统for循环——当前采用这种写法,最易读squared=[]forxinrange(10):squared.append(x**2)print(squared)

八、本篇小结

✅ 注释是写给人的,不是写给机器的。机器根本看不懂你的注释,但三个月后的你自己会感激今天的注释。

核心要点回顾:

  1. 三种注释方式#单行、'''/"""多行、docstring文档字符串
  2. 注释解释"为什么",不要只重复"是什么"
  3. 保持注释和代码同步,过时的注释比没有注释更危险
  4. 好的命名是注释的替代品——当代码自己就能说清楚意思时,不需要额外注释
  5. 关键逻辑必须注释:算法原理、业务规则、特殊限制、已知问题

💡 写注释是一种代码素养。它不是额外的负担,而是编码过程中自然的一部分。从今天开始,每写一段代码,养成问自己"别人读到这里能明白吗"的习惯。下一篇我们将进入Python的基础语法——缩进规则和代码块规范。

http://www.cnnetsun.cn/news/2750475.html

相关文章:

  • 深度探索Android内核扩展:构建安全高效的系统hook模块
  • VisualCppRedist AIO:终极Windows运行库修复解决方案
  • 如何高效下载抖音视频:douyin-downloader完整指南与实战技巧
  • 2026降AI率工具红黑榜:降AI率网站怎么选?别再瞎找了!
  • 如何用OpenMir2快速搭建热血传奇游戏服务器:C完整实战指南
  • 高校心理教育辅导设计与实现 | 毕业设计完整源码
  • 基于LPJ模型的植被NPP模拟、驱动力分析及其气候变化响应预测
  • date-fns:200+ 函数的 JavaScript 日期工具库
  • 2026 电商爆单密码:怎么用 AI 生成带货视频?高性价比工具深度盘点
  • 高灵敏+高特异 | 多疾病领域小分子ELISA试剂盒优选方案
  • GPT-5.4 Pro静默升级深度解析:推理加速与多模态优化实战指南
  • 番茄小说下载器:打造个人专属离线图书馆的终极指南 [特殊字符]
  • 从安装到调参:一份超详细的imbalanced-learn避坑指南(含版本依赖与常见报错解决)
  • ORB-SLAM Atlas里的‘相机位姿可观测性’到底在防什么坑?一个公式讲清多地图的精度秘密
  • MATLAB最小费用最大流求解工具包:含Ford-Bellman增广路径实现
  • 2026年3月三级T2:上升三元组
  • 5k Star的直播自动录制工具biliup,支持20+平台持续录像上传
  • (ASP + Access)网页版文档文件(证照、档案、合同等)管理系统
  • 如何用Python构建同花顺自动化交易系统:jqktrader技术深度解析
  • 别只画图了!深度挖掘VOSviewer三大视图(网络/覆盖/密度)背后的科研故事与隐藏信息
  • 基于STM32的4000W数字交流调光器:从原理到实战设计
  • 跳出模板化写作桎梏:okbiye 以分层式毕业论文创作逻辑重构毕业生撰写新范式
  • 2026年6月效果好、服务稳定的GEO服务商有哪些
  • 别再手动敲了!用WPS宏一键搞定汉字转拼音首字母(附完整代码和避坑指南)
  • 从零打造可穿戴电子徽章:ATmega32U4与WS2812B的硬件艺术实践
  • 大学生刚毕业,在上海初创四人公司学习嵌入式第三天
  • 告别英文界面焦虑:Axure RP中文语言包让原型设计更轻松
  • 别再问银行账户怎么建了!S/4 HANA Fiori版‘FI12’配置全流程指南
  • 英语学习之每日单词
  • 风光储能源电站远程监控可视化管理系统方案