数据STUDIO

还在用if-else堆代码?这10个Python技巧让你的代码优雅10倍

Image
你的未来自己,会感谢你今天的每一次重构。

我接手过一些代码——来自很牛的开发者,却依然让我盯着屏幕发呆:“等等……这到底在做什么?”

这种停顿,代价很大。

可读性高的代码,不是代码写得少,而是代码写得明显。它不需要注释就能自解释,不需要发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 = {}

你的变量名应该回答:“这个东西为什么存在?”

而不是“它是什么类型”。

写在最后

技术债务不总是那些“大重构”。更多时候,它是每天写下一段自己都不想看的代码,然后告诉自己“以后再说”。

我见过太多团队在“可读性”上口惠而实不至——代码审查时只查逻辑错误,却放任认知负担一点点堆积。直到新人入职需要两周才能上手,直到线上故障定位需要三个小时。

好的代码,是写给下一个维护者的一封信。而这个维护者,很可能就是六个月后的你。

你今天写的每一行“明显的代码”,都是未来的你少掉的一根头发。

核心回顾

  1. 意图优先:用枚举替代布尔、用函数名替代注释、用常量替代魔法数字
  2. 结构扁平:卫语句、垂直间距、字典映射替代 elif
  3. 沟通显式:_ 表达忽略、命名元组替代字典、变量名表达角色而非类型

你在代码审查中最常遇到的“可读性反模式”是什么?如果要在团队推行这10个技巧,你觉得哪个阻力最大?欢迎留言聊聊你的实战经验。 

🏴‍☠️宝藏级🏴‍☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉Python|MySQL|数据分析|数据可视化|机器学习与数据挖掘|爬虫等,从入门到进阶!

长按👇关注- 数据STUDIO -设为星标,干货速递ImageImage