还在用if-else堆代码?这10个Python技巧让你的代码优雅10倍
你的未来自己,会感谢你今天的每一次重构。
我接手过一些代码——来自很牛的开发者,却依然让我盯着屏幕发呆:“等等……这到底在做什么?”
这种停顿,代价很大。
可读性高的代码,不是代码写得少,而是代码写得明显。它不需要注释就能自解释,不需要发Slack问同事,更不用六个月后自己打开文件时,内心充满疑惑。
今天分享10个我每天都在用的可读性技巧。大部分Python开发者都知道,但真正用对的,没几个。
1. 用枚举类替代布尔标志
布尔标志是可读性的第一杀手。
# ❌ 糟糕的写法
defprocess(data, fast=True, safe=False):
...
# 调用代码:fast=True, safe=False 是什么意思?
process(user_data, True, False)
现在不看函数定义,你能回答:fast=True, safe=False 代表什么业务含义吗?
改用意图清晰的枚举类:
# ✅ 可读的写法
classMode:
FAST = "fast"
SAFE = "safe"
DEBUG = "debug"
defprocess(data, mode: str):
# 根据mode执行不同逻辑
...
process(data, mode=Mode.FAST)
你的大脑阅读的是单词,不是布尔值。这能瞬间减轻认知负担。
⚠️ 注意:这里90%的人会踩坑
有人会说“那我用注释解释布尔值不就行了?”——注释会过时,但类型安全不会。更何况,当你需要三个模式时,布尔值组合会指数级膨胀(fast=True, safe=False, debug=True),而枚举只需要增加一个成员。
2. 用卫语句(Guard Clauses)展平逻辑
嵌套的条件判断,是可读性的债务。
糟糕的写法:
defsave(user):
if user:
if user.is_active:
if user.has_permission:
persist(user)
这段代码的逻辑路径,你需要用眼睛“走迷宫”。
可读的写法:
defsave(user):
ifnot user:
return
ifnot user.is_active:
return
ifnot user.has_permission:
return
persist(user)
这就像外卖骑手等单:不符合条件就立刻退出,不堆积判断。扁平化的代码,就是可读的代码。你的眼睛不需要地图就能跟上执行路径。
3. 给中间变量起名字,而不是内联表达式
内联逻辑看起来“聪明”,但读起来很费劲。
# ❌ 难以理解
if request.user.profile.settings.preferences.theme.color == "dark":
apply_dark_mode()
这个链式访问,读一遍要花多久?
可读的写法:
# ✅ 引入语义化检查点
preferences = request.user.profile.settings.preferences
theme_color = preferences.theme.color
if theme_color == "dark":
apply_dark_mode()
你没有增加代码行数,你增加的是清晰度。
4. 用 _ 传递信号:“这个值存在,但我不用”
Python 的 _ 不是装饰品,它是沟通工具。
# 遍历时忽略文件名,只处理子目录
for _, filename in os.walk(directory):
process(filename)
或者在解包时:
user_id, _, email = get_user_data() # 中间的值是废弃字段
它在告诉未来的读者:“是的,这里有个值。不,它不重要。”
这种坦诚,很重要。
5. 用函数提取替代注释
如果你觉得需要写注释来解释某段代码在做什么——直接提取成一个函数。
糟糕的写法:
# 检查用户是否有权限访问仪表盘
if user.is_authenticated and user.is_active andnot user.is_banned:
show_dashboard()
可读的写法:
defcan_access_dashboard(user):
return (
user.is_authenticated
and user.is_active
andnot user.is_banned
)
if can_access_dashboard(user):
show_dashboard()
现在代码读起来像英语——注释变得多余了。
⚠️ 注意:函数命名要精确
check_user这种命名就是反面教材。命名应该回答“为什么”,而不是“是什么”。can_access_dashboard直接表达了意图。
6. 用命名元组(NamedTuple),别用字典
字典用字符串键传递数据,含义藏在引号后面。
# ❌ 返回字典,结构不透明
return {
"min": min_value,
"max": max_value,
"avg": average
}
# 调用方:return_value["avg"] 还是 return_value["average"]?
可读的替代方案:
from collections import namedtuple
Stats = namedtuple("Stats", ["min", "max", "avg"])
defcalculate_stats(data):
# ...计算逻辑
return Stats(min_value, max_value, average)
# 调用时
stats = calculate_stats(data)
print(stats.avg) # IDE 自动补全可用
现在:
自动补全可用 重构更安全(IDE能追踪字段引用) 读者一眼就知道返回结构
7. 用垂直间距表达逻辑层次
空白不是装饰——它是语法。
无间距版本:
validate_input(data)
normalize(data)
save(data)
notify_user()
log_event()
这四个步骤是平铺的,读者不知道哪几行是同一阶段。
有间距版本:
validate_input(data)
normalize(data)
save(data)
notify_user()
log_event()
每个空行,都是一个逻辑阶段的切换:
阶段1:验证与标准化 阶段2:持久化 阶段3:后置通知
你的大脑能本能地理解这种分组。
8. 用领域常量替换魔法数字
魔法数字让代码撒谎。
if retries > 3:
abort()
3 是什么?为什么是 3?
可读的写法:
MAX_RETRIES = 3
if retries > MAX_RETRIES:
abort()
这不只是为了常量——这是为了讲述数字背后的故事。当你读代码时,你看到的是“超过最大重试次数”,而不是一个孤立的数字。
⚠️ 注意:常量要放在正确的位置
别把MAX_RETRIES = 3写在函数内部。这会导致重复定义和维护困难。应该放在模块顶部或配置类中,让所有相关代码共享同一个定义。
9. 少用 elif(比你想象中更少)
elif 隐藏了决策树的结构。
# 当状态增多时,这段代码会膨胀
if status == "pending":
handle_pending()
elif status == "approved":
handle_approved()
elif status == "rejected":
handle_rejected()
当逻辑变复杂时,改用字典映射:
handlers = {
"pending": handle_pending,
"approved": handle_approved,
"rejected": handle_rejected,
}
handlers[status]()
现在行为是数据驱动的,不是条件堆砌。新增状态只需在字典中添加一行,而不是再加一个 elif。
这个模式尤其适合处理状态机、命令分发、RPC路由等场景。国内很多微服务框架的请求分发,底层就是这么做的。
10. 根据“角色”命名变量,而不是“类型”
类型会变,角色不会。
糟糕的写法:
list_of_users = []
dict_of_settings = {}
可读的写法:
users = []
settings = {}
或者更进一步,表达业务角色:
active_users = []
feature_flags = {}
你的变量名应该回答:“这个东西为什么存在?”
而不是“它是什么类型”。
写在最后
技术债务不总是那些“大重构”。更多时候,它是每天写下一段自己都不想看的代码,然后告诉自己“以后再说”。
我见过太多团队在“可读性”上口惠而实不至——代码审查时只查逻辑错误,却放任认知负担一点点堆积。直到新人入职需要两周才能上手,直到线上故障定位需要三个小时。
好的代码,是写给下一个维护者的一封信。而这个维护者,很可能就是六个月后的你。
你今天写的每一行“明显的代码”,都是未来的你少掉的一根头发。
核心回顾
意图优先:用枚举替代布尔、用函数名替代注释、用常量替代魔法数字 结构扁平:卫语句、垂直间距、字典映射替代 elif沟通显式: _表达忽略、命名元组替代字典、变量名表达角色而非类型
你在代码审查中最常遇到的“可读性反模式”是什么?如果要在团队推行这10个技巧,你觉得哪个阻力最大?欢迎留言聊聊你的实战经验。
🏴☠️宝藏级🏴☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉Python|MySQL|数据分析|数据可视化|机器学习与数据挖掘|爬虫等,从入门到进阶!
长按👇关注- 数据STUDIO -设为星标,干货速递