小白学 Python
课程GitHub
© 2026 小白学 Python · 基于 walter201230/Python 教程
课程目录GitHub
Python 环境加载中…
代码可读性0 / 4
1234

代码可读性

4 道练习题·预计 40 分钟·做对一题解锁下一段

教学 05 / 05

第十七节:代码可读性

学到这里,你已经能写出能跑的 Python 代码了。但「能跑」和「好读」是两回事。

看这段代码:

python
def calc(x, y, op):
    if op == 'add':
        return x + y
    elif op == 'sub':
        return x - y

读到这个函数,你的第一反应是什么?

  • x 和 y 是数字还是字符串?
  • op 还能传啥?
  • 返回值是啥类型?返回 None 怎么办?

只能去翻调用方的代码——或者直接去问写代码的人。

「能跑」 ≠ 「好代码」

代码不是只写给电脑看的——更多时候是写给:

  • 半年后的自己(你会忘)
  • 接手项目的同事(他不知道你当时怎么想)
  • Code Review 的 reviewer(他要在 5 分钟内看懂你的意图)

所以「好读」是一项必须练的能力。

这一节要学什么

主题解决什么问题
好命名一眼看懂这个变量/函数是干嘛的
早返回把 6 层嵌套的 if 摊平
推导式把 4 行 for 循环压成 1 行
类型注解让函数签名自带文档

学完这一节,你写出来的 Python 代码会专业一大截。

教学 01 / 05· 已读

一、好命名

写代码 80% 的时间在「读」,只有 20% 在「写」。所以命名好不好,直接决定代码读起来累不累。

1、变量用名词,函数用动词

变量装的是「东西」——用名词:

python
user_name = '张三'
total_price = 100
order_list = []

函数做的是「动作」——用动词或动词短语:

python
def get_user(uid): ...
def calculate_total(items): ...
def send_email(to, body): ...

反例(让读者皱眉):

python
def user(uid): ...        # 这是函数还是属性?
def data(items): ...       # 处理 data?还是返回 data?

2、布尔值用 is_ / has_ / can_ 开头

python
is_active = True       # 一眼看出是布尔
has_permission = False
can_edit = True

反例:

python
active = True          # active 是状态值还是布尔?要去看赋值才知道
permission = False     # 这是权限对象还是 True/False?

3、避免无意义的缩写

python
# 不好
def calc(u, p):
    return u * p

# 好
def calculate_total(unit_price, quantity):
    return unit_price * quantity

注意:通用缩写(比如 i 当循环变量、url、id、db)大家都懂,可以用。但 usr、prc、amt 这种「省两个字母」的缩写就别写了,省的那点字符根本不值得读者去猜。

4、长度跟作用域成正比

python
for i in range(10):       # i 作用域很小,用一个字母没问题
    print(i)

# 但模块级的全局变量就要起得清楚
USER_ROLE_ADMIN = 'admin'
DEFAULT_TIMEOUT_SECONDS = 30

一句话总结

看到这个名字,读者还要不要去翻定义才能懂?要——名字没起好。

教学 02 / 05

二、早返回(Early Return)

来看下面这段「校验登录」的代码:

python
def login(user, password):
    if user is not None:
        if user.is_active:
            if user.check_password(password):
                if not user.is_locked:
                    return '登录成功'
                else:
                    return '账户已锁定'
            else:
                return '密码错误'
        else:
            return '账户未激活'
    else:
        return '用户不存在'

四层嵌套——读到第三层 if 时,你已经记不清第一层的条件是什么了。

早返回:把异常情况先送走

「先处理边界情况,主流程才能放在最外层」——这就是早返回的核心思想。

python
def login(user, password):
    if user is None:
        return '用户不存在'
    if not user.is_active:
        return '账户未激活'
    if not user.check_password(password):
        return '密码错误'
    if user.is_locked:
        return '账户已锁定'
    return '登录成功'

变化看出来了吗?

  • 没有 else
  • 没有嵌套
  • 每个失败条件只占一行
  • 最后一行是「成功路径」——一眼就能找到

通用模式

凡是看到这种结构:

python
if 条件成立:
    # 主流程一大段
    ...
else:
    return 错误

都可以改写成:

python
if not 条件成立:
    return 错误
# 主流程一大段(无缩进)
...

主流程从 1 层缩进退回到 0 层。多个条件叠加时效果尤为明显。

什么时候不用早返回

不是所有 if 都该早返回。如果两个分支地位平等——比如「奇数返回 X、偶数返回 Y」——那就老老实实写 if/else,没必要硬塞进早返回。

python
def parity(n):
    if n % 2 == 0:
        return '偶数'
    else:
        return '奇数'

这样反而清楚。早返回是为了摊平错误处理,不是为了消灭所有 else。

练习 1 / 4·用早返回重写嵌套 if题目有问题?

下面这段函数 check(score) 用了三层嵌套——请用早返回重写一个函数 check(score),逻辑保持一致:

  • score < 0 或 score > 100:返回 '非法分数'
  • score >= 90:返回 '优秀'
  • score >= 60:返回 '及格'
  • 其他:返回 '不及格'

然后依次调用 print(check(95))、print(check(72))、print(check(40))、print(check(150))。

输出应该是:

优秀
及格
不及格
非法分数

提示:用「早返回」就是先把异常情况先 return 掉,把主流程留在最外层,不写 else、不嵌套。

main.py
可编辑
🔒做对当前题解锁下一段 ·0/4
本章目录

代码可读性

  1. 教学 05第十七节:代码可读性
  2. 教学 01一、好命名
  3. 教学 02二、早返回(Early Return)
  4. 练习 1用早返回重写嵌套 if
  5. 教学 03三、推导式(Comprehension)
  6. 练习 2 🔒列表推导式:挑出正数并平方
  7. 练习 3 🔒字典推导式:把所有价格翻倍
  8. 教学 04四、类型注解(Type Hints)
  9. 练习 4 🔒写一个带类型注解的函数
← 上一章16 · 装饰器
代码可读性
下一章 →18 · pathlib:现代化路径处理