第1章 变量与注释-Python工匠:案例、技巧与工程实践
🧭 一、核心目标:让代码“可读、可维护、可信任”
这一章的核心思想不是语法,而是 写给人看的代码。
变量和注释虽然不会改变执行逻辑,却直接决定别人(包括未来的你)是否能理解你的意图。
写给人读的代码,才是可维护的代码。
🧩 二、变量部分(实践重点)
1. 变量定义与解包
-
解包赋值 (unpacking) 比
index
操作更直观:username, *fruits, score = ['piglei', 'apple', 'orange', 'banana', 100]
✅ 直观、少错误
❌ 不要忘记:左边变量数要和右边结构对应。
🔧 开发场景:解析结构化数据(如 API 响应 / CSV 行)时,比手动切片更安全、可读性更强。
2. 单下划线 _
用法
-
用作占位符变量(表示不关心的值):
name, _ = ('raymond', 42)
-
在交互式解释器中,
_
保存上一个表达式结果。
🧠 注意:生产代码中用
_
占位要谨慎,日志或调试代码里容易混淆。
3. 类型注解(Type Hints)
动态语言要靠类型提示补充可读性与安全性。
from typing import Listdef remove_invalid(items: List[int]) -> None:...
收益:
- IDE 自动提示、补全;
- 静态检查工具(如
mypy
)发现类型错误; - 新同事上手快。
💡 实际经验:
- 中大型项目必须使用类型注解(哪怕是部分添加);
- 小脚本或原型可不加,但写公共库必须加。
4. 变量命名原则(精华)
原则 | 说明 | 示例 |
---|---|---|
遵循 PEP8 | 蛇形命名(snake_case),常量全大写 | max_value , MAX_LIMIT |
描述性要强 | 不要用 data 、temp 、result 这类模糊词 | ✅ active_users , pending_id |
名字要短 | 在上下文明确时精简 | level3_points 而非 how_many_points_needed_for_user_level3 |
匹配类型 | 名字暗示数据类型 | is_active , users_count , user_id |
超短名要慎用 | 除非约定俗成 (i , s , e , _ ) | ❌ t , d , x 没意义 |
🧩 实践经验:
- 命名是可读性的根基;
- 若变量名太长说明职责不清,可通过函数封装简化;
- 尝试先用注释描述,再提炼出最简洁的命名。
5. 一致性与作用域控制
- 同一概念同一命名:不要
avatar_url
一会儿变成profile_url
。 - 类型一致性:不要让变量名在不同地方类型不同。
✅ 若确实需要变化,就新建变量,比如
user_list
vsusers_dict
。
6. 变量定义位置
“定义要靠近使用。”
# ❌ 坏习惯:统一放最上面
waypoints = []
photo_markers = []
...# ✅ 好习惯:逻辑块内初始化
# 初始化 waypoints 数据
waypoints = []
...
# 处理 photo_markers
photo_markers = []
...
📍 实践经验:
在长函数中靠近使用点定义变量,可以显著提升可读性和减少上下滚动。
7. 临时变量 vs 冗余变量
-
✅ 定义临时变量能提升表达力:
user_is_eligible = user.is_active and (user.sex == 'female' or user.level > 3) if user_is_eligible:user.add_coins(10000)
-
❌ 但别滥用:
# 不必要的中间变量 user = get_user(user_id) trip = get_best_trip(user_id) return {'user': user, 'trip': trip}
→ 改为一行:
return {'user': get_user(user_id), 'trip': get_best_trip(user_id)}
🧠 原则:变量存在的唯一理由,是让代码更好理解或减少重复。
🗒️ 三、注释部分(核心经验)
1. 三种常见错误
错误类型 | 示例 | 改进建议 |
---|---|---|
屏蔽代码 | # old_version() | ❌ 直接删除,用 Git 管 |
复述代码 | # 调用 strip 去空格 | ❌ 无价值,应说明“为什么” |
接口注释写实现细节 | 长篇讲底层逻辑 | 仅写“功能与使用方式” |
2. 注释的层次
-
代码注释:描述代码段的意图或背景。
-
接口注释(docstring):描述函数/类的用途、参数、返回值。
def resize_image(image, size):"""将图片缩放到指定尺寸并返回。注意:文件 >5MB 时请用 resize_big_image()"""
-
指引性注释:对代码逻辑块的简要说明(如“# 初始化 client”)。
📘 实际建议:
- “注释说明为什么,而不是怎么做。”
- 当函数命名能表达意图时,优先通过命名替代注释。
3. 空行也是注释
空行能分隔逻辑块,是视觉层面的“注释”:
if should_swap:numbers[i], numbers[i + 1] = numbers[i + 1], numbers[i]stop_position -= 1
return numbers
没有空行的代码读起来像“一口气没断气”。
4. 写注释的最佳时机
“先写注释,后写代码。”
原因:
- 帮助你思考函数职责是否单一;
- 确保不会忘记写 docstring;
- 写注释的过程本身是设计 API 的过程。
🔧 四、项目级实战建议(可落地)
场景 | 应用建议 |
---|---|
团队项目 | 全面使用类型注解 + PEP8 命名规范 |
新功能开发 | 函数起名 + 注释先写,逻辑后补 |
代码评审(Code Review) | 检查变量一致性、注释有效性 |
日常维护 | 删除注释掉的旧代码、保持空行结构 |
大型函数 | 用数据类或嵌套对象封装局部变量群 |
Web模板渲染 | 明确列出变量,避免 locals() |
📦 五、总结:这章在实战中的价值
主题 | 在工程实践中的作用 |
---|---|
命名规范 | 提升跨人协作可读性 |
类型注解 | 减少接口误用、方便静态检查 |
注释与空行 | 提高理解效率、降低维护成本 |
一致性与精简性 | 保证代码“整洁”与“信任感” |