📄 本篇摘要
代码的第一读者不是计算机,是半年后的你自己。本篇讲可读性三基石:注释(说为什么,不说是什么)、缩进(用空白把结构画出来——Python 里甚至直接是语法)、嵌套(层数越深脑子越炸,能扁则扁)。
📝 关系
上一节:字符串查找与 BM 算法 | 下一节:命名规则与编码规范 本章主题:怎么写、怎么测、怎么管——从设计到测试的开发方法,后半章进入面向对象。
一、代码是写给人看的
计算机不挑食——写成什么样它都能跑。可读性是为了人:读代码的时间通常远多于写代码的时间(接手别人的、三个月后回看自己的)。所以「能跑就行」远远不够,可读性是一种成本:现在多花一分钟整理,未来省下十分钟猜谜。
二、注释:说为什么,不说是什么
# 坏注释:翻译代码(代码本身就说明了是什么)
i += 1 # i 加 1
# 好注释:解释代码说不出来的部分
retry -= 1 # 最多重试 3 次:支付接口偶发超时,超过 3 次大概率是网络故障而非抖动
三条纪律:
- 说 why 不说 what——「做了什么」代码自己会说话;「为什么这么做」只有注释能说。
- 注释会过期——改了代码不改注释,比没注释更害人。注释跟着代码一起维护。
- 名字够好就不需要注释——
retry_count不用注释,rc必须注释。先取好名,注释是最后手段。
教材还提醒:文档字符串(docstring,如 Python 的
"""...""")是写给【使用者】的说明书,普通注释是写给【维护者】的便签——两者用途不同。
三、缩进:用空白画结构
缩进展示层级:哪段属于哪个 if、哪个循环。Python 更进一步——缩进直接就是语法(4.6 节树莓派课讲过:挪一格就改逻辑)。
# 缩进即结构:一眼看出两层
for student in students:
if student.score >= 60:
print(student.name, "及格")
两条纪律:
- 同一项目用同一缩进宽度(Python 社区标准=4 空格;禁止 Tab 与空格混用——混用是 Python 2 时代著名的隐形炸弹)。
- 空行也是缩进的一部分——逻辑段落之间空一行,比密密麻麻舒服得多。
四、嵌套:层数是复杂度的直接度量
# 嵌套三层:读的时候要在脑子里压一层栈
for order in orders:
if order.paid:
for item in order.items:
if item.stock > 0:
ship(item)
# 护卫句(早返回)拍平一层
for order in orders:
if not order.paid:
continue
for item in order.items:
if item.stock > 0:
ship(item)
经验法则:嵌套不超过三层。再深就动手术——提前返回(continue/return)、抽函数、翻转条件。嵌套深度是第 5-8 节【软件指标】里圈复杂度的近亲:层数越深,测试路径越爆炸。
五、动手 Demo:亲手感受嵌套税
# 找出所有及格学生的姓名,要求:已选课 且 有成绩
students = [
{"name": "波仔", "enrolled": True, "score": 88},
{"name": "小明", "enrolled": False, "score": 95},
{"name": "小红", "enrolled": True, "score": 40},
]
# 版本一:三层嵌套
def pass_names_v1(data):
result = []
for s in data:
if s["enrolled"]:
if s["score"] is not None:
if s["score"] >= 60:
result.append(s["name"])
return result
# 版本二:护卫句拍平(行为完全相同)
def pass_names_v2(data):
result = []
for s in data:
if not s["enrolled"]:
continue
if s["score"] is None:
continue
if s["score"] < 60:
continue
result.append(s["name"])
return result
print(pass_names_v1(students))
print(pass_names_v2(students))
print(pass_names_v1(students) == pass_names_v2(students))
沙箱实跑输出:
['波仔']
['波仔']
True
看到什么算成功:两版输出一致、第三行 True 证明行为没变。
读结果:版本二每行只处理一个条件、失败就早早离开——行数多了两行,但每一行的脑力成本减半。可读性优化的典型账目。
六、30 秒实验
打开浏览器控制台或任意 Python:把 5-1 Demo 里的 s["score"] >= 60 改成 s["score"] > 60——波仔(88)还在,想想 60 分整的同学去哪了?边界差异就是这样藏进一行的(5-6 边值分析正要治它)。
七、常见误区
| 误区 | 真相 |
|---|---|
| 注释越多越专业 | 好名字+好结构才是主力;翻译式注释是噪音 |
| 缩进只是美观 | Python 里缩进是语法,错了直接报错或改逻辑 |
| 嵌套深=逻辑严密 | 层数越深测试路径越指数级变多(5-8 圈复杂度) |
自测三问(点击展开)
1. **好注释和坏注释的分界线是什么?** 答:说【为什么】的是好注释,翻译【是什么】的是坏注释——后者代码自己就能说。 2. **Python 的缩进和 C++ 的缩进有什么本质区别?** 答:C++ 缩进只是给人类看的,靠大括号定结构;Python 缩进本身就是语法,挪一格就改逻辑。 3. **嵌套太深的第一手术方案是什么?** 答:翻转条件+提前返回(护卫句),把异常路径逐层拍平。- ☐ 5-1 学习完成
相关笔记
- 树莓派 6-4 · Python 流程控制 —— 缩进即语法的现场
- 静态分析与软件指标 —— 嵌套深度变成可测的数字
- ⌨️ 编程原理 · 索引 —— 全课路线图