4 道练习题·预计 40 分钟·做对一题解锁下一段
学到这里,你已经能写出能跑的 Python 代码了。但「能跑」和「好读」是两回事。
看这段代码:
def calc(x, y, op):
if op == 'add':
return x + y
elif op == 'sub':
return x - y读到这个函数,你的第一反应是什么?
x 和 y 是数字还是字符串?op 还能传啥?None 怎么办?只能去翻调用方的代码——或者直接去问写代码的人。
代码不是只写给电脑看的——更多时候是写给:
所以「好读」是一项必须练的能力。
| 主题 | 解决什么问题 |
|---|---|
| 好命名 | 一眼看懂这个变量/函数是干嘛的 |
| 早返回 | 把 6 层嵌套的 if 摊平 |
| 推导式 | 把 4 行 for 循环压成 1 行 |
| 类型注解 | 让函数签名自带文档 |
学完这一节,你写出来的 Python 代码会专业一大截。
写代码 80% 的时间在「读」,只有 20% 在「写」。所以命名好不好,直接决定代码读起来累不累。
变量装的是「东西」——用名词:
user_name = '张三'
total_price = 100
order_list = []函数做的是「动作」——用动词或动词短语:
def get_user(uid): ...
def calculate_total(items): ...
def send_email(to, body): ...反例(让读者皱眉):
def user(uid): ... # 这是函数还是属性?
def data(items): ... # 处理 data?还是返回 data?is_ / has_ / can_ 开头is_active = True # 一眼看出是布尔
has_permission = False
can_edit = True反例:
active = True # active 是状态值还是布尔?要去看赋值才知道
permission = False # 这是权限对象还是 True/False?# 不好
def calc(u, p):
return u * p
# 好
def calculate_total(unit_price, quantity):
return unit_price * quantity注意:通用缩写(比如 i 当循环变量、url、id、db)大家都懂,可以用。但 usr、prc、amt 这种「省两个字母」的缩写就别写了,省的那点字符根本不值得读者去猜。
for i in range(10): # i 作用域很小,用一个字母没问题
print(i)
# 但模块级的全局变量就要起得清楚
USER_ROLE_ADMIN = 'admin'
DEFAULT_TIMEOUT_SECONDS = 30看到这个名字,读者还要不要去翻定义才能懂?要——名字没起好。
来看下面这段「校验登录」的代码:
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 时,你已经记不清第一层的条件是什么了。
「先处理边界情况,主流程才能放在最外层」——这就是早返回的核心思想。
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凡是看到这种结构:
if 条件成立:
# 主流程一大段
...
else:
return 错误都可以改写成:
if not 条件成立:
return 错误
# 主流程一大段(无缩进)
...主流程从 1 层缩进退回到 0 层。多个条件叠加时效果尤为明显。
不是所有 if 都该早返回。如果两个分支地位平等——比如「奇数返回 X、偶数返回 Y」——那就老老实实写 if/else,没必要硬塞进早返回。
def parity(n):
if n % 2 == 0:
return '偶数'
else:
return '奇数'这样反而清楚。早返回是为了摊平错误处理,不是为了消灭所有 else。
下面这段函数 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、不嵌套。