第2章:命名规范与代码风格——写出让人舒服的代码
说实话,我见过太多能跑但没法维护的代码了。逻辑没问题,性能也还行,可就是读起来像天书。变量名叫 a、b、tmp,函数名全是 do_stuff、process_data。你想想看,三个月后你自己回来看,估计都得挠头。
这一章咱们就聊聊怎么把代码写「干净」。说白了,就是让代码自己会说话。
2.1 命名原则:一个好名字胜过一行注释
我个人的习惯是:命名要能准确表达意图。别怕名字长,怕的是名字误导人。
2.1.1 变量命名
- 使用有意义的名称:
user_count比uc好,is_active比flag好 - 布尔变量用 is/has/can 开头:
is_valid、has_permission、can_edit - 避免通用词:
data、info、temp尽量少用 - 常量全大写加下划线:
MAX_RETRY_COUNT = 3
✅ 好例子
# 糟糕的命名
x = get_data()
y = x * 1.2
if y > 100:
do_something()
# 好的命名
base_price = get_product_price()
discounted_price = base_price * 1.2
if discounted_price > MAX_DISCOUNT_THRESHOLD:
apply_special_approval()
2.1.2 函数命名
函数名应该是一个动词或动词短语。我在项目中遇到过有人写 user() 这个函数,你猜它是获取用户、创建用户还是删除用户?猜不到。
- 动作 + 对象:
create_user()、delete_order()、send_email() - 返回布尔值用 is/has/can:
is_available()、has_access() - 避免模糊词:
handle()、process()、do()
2.1.3 类命名
类名用名词,首字母大写驼峰。我见过有人把类名写成 user_manager,小写下划线——这其实是模块的命名风格,容易混淆。
| 类型 | 风格 | 示例 |
|---|---|---|
| 类 | PascalCase | UserProfile、OrderService |
| 函数/方法 | snake_case | get_user_by_id()、send_notification() |
| 变量 | snake_case | user_name、order_total |
| 常量 | UPPER_SNAKE_CASE | MAX_CONNECTIONS、DEFAULT_TIMEOUT |
| 私有属性/方法 | 前导下划线 | _internal_cache、_validate_input() |
⚠️ 我曾经踩过的坑
我曾经把一个变量命名为 list,结果覆盖了 Python 内置的 list 类型。后面代码里用 list() 构造列表时直接报错。排查了半小时才发现是命名冲突。所以记住:永远不要用 Python 关键字或内置函数名做变量名。
2.2 PEP 8 规范:Python 社区的通用语言
PEP 8 是 Python 的官方风格指南。说白了,就是大家约定俗成的写法。你不遵守也能跑,但团队协作时就会很痛苦。
2.2.1 缩进与空格
- 4 个空格缩进,不要用 Tab。我见过混用 Tab 和空格的代码,那格式简直没法看
- 每行不超过 79 个字符,文档字符串/注释不超过 72 个字符
- 二元运算符前后各加一个空格:
a = b + c而不是a=b+c - 函数参数列表的逗号后加空格:
func(a, b, c)
✅ 正确的缩进示例
# 函数参数换行对齐
def create_user(
name,
email,
age=None,
is_active=True
):
# 函数体缩进 4 个空格
user = User(name=name, email=email)
if age is not None:
user.age = age
return user
2.2.2 空行与注释
- 顶级函数和类之间空两行
- 类内方法之间空一行
- 注释用英文或中文都可以,但团队内要统一。我个人习惯用英文注释,因为和代码风格更一致
- 注释要解释「为什么」,而不是「是什么」。代码本身已经说明了「是什么」
# 不好的注释
x = x + 1 # 给 x 加 1
# 好的注释
x = x + 1 # 补偿循环中的 off-by-one 误差
2.2.3 import 规范
import 语句要按顺序分组,每组之间空一行:
- 标准库
- 第三方库
- 本地应用/库
import os
import sys
import requests
import yaml
from myproject.models import User
from myproject.utils import format_date
2.3 代码格式化工具:让机器帮你干活
手动调整格式?太累了。我建议直接用工具,一劳永逸。
2.3.1 Black:毫不妥协的格式化器
Black 号称「不妥协的代码格式化器」。你用它的规则,它帮你格式化,你没得选。这其实是好事——团队里不用再争论「花括号放哪行」这种问题了。
💡 安装与使用
# 安装
pip install black
# 格式化单个文件
black my_script.py
# 格式化整个目录
black my_project/
# 检查但不修改
black --check my_script.py
Black 的默认配置很合理:每行 88 个字符(比 PEP 8 的 79 宽松一点)、强制使用双引号、自动处理尾随逗号。我在项目中直接把它配到 pre-commit hook 里,提交代码前自动格式化。
2.3.2 autopep8:更温和的选择
如果你觉得 Black 太霸道,可以用 autopep8。它只修复 PEP 8 违规,不会大改你的代码风格。
# 安装
pip install autopep8
# 格式化文件
autopep8 --in-place my_script.py
# 显示差异但不修改
autopep8 --diff my_script.py
我个人更推荐 Black。为什么?因为 autopep8 给了太多选项,团队里还是会有争论。Black 直接一刀切,省心。
2.3.3 集成到编辑器
不管用 VSCode、PyCharm 还是 Vim,都可以配置保存时自动格式化:
| 编辑器 | 配置方式 |
|---|---|
| VSCode | 设置 "editor.formatOnSave": true,选择 Black 作为格式化器 |
| PyCharm | 安装 Black 插件,配置 File Watchers 或外部工具 |
| Vim | 使用 black 插件或 :!black % |
2.4 本章知识体系
下面这张图帮你理清命名规范与代码风格的核心脉络:
💡 我的个人建议
刚开始写代码时,别太纠结风格。先跑通功能,然后养成习惯:写完代码后用 Black 格式化一遍。慢慢地,你就会形成肌肉记忆,写出来的代码自然就符合规范了。
嗯,这一章的内容就到这里。命名规范和代码风格看起来是小事,但直接影响代码的可维护性。记住一句话:好代码是让人能轻松理解的代码。