集点卡说第十杯免费,但只限十一点前,节假日还不算。一条 if 管得住第一条规则,第二条就开始叠了。缩进到底在决定哪几行属于同一个分支?
当程序能对不同值做出反应时,它才开始有用。条件语句只在测试为真时执行一段代码。Python 用缩进表示哪些行属于同一个分支。 你还会用守卫子句替代深层嵌套,并测试边界值。
比较运算产生布尔值
== 判断相等,!= 判断不等,<、<=、>、>= 用于比较大小。比较的结果是 True 或 False。不要把 =(赋值)和 ==(比较)混淆。
score = 85
print(score >= 80)
print(score == 100)
print(score != 0)比较结果
只走一个分支
if 在条件为真时执行。elif 只会在前面的条件都为假时检查。else 接收剩下的所有情况。顺序很重要:通常把更严格或更高的阈值放在前面。
score = 85
if score >= 90:
print("A")
elif score >= 80:
print("B")
else:
print("C")成绩等级
组合多个条件
and 只有在两边都为真时才为真。or 只要至少一边为真就为真。not 会翻转布尔值。复杂条件加上括号会更容易读。
age = 20
member = True
print(age >= 18 and member)
print(age < 18 or member)
print(not member)布尔逻辑
守卫子句让嵌套保持扁平
当一个函数有多个前置条件时,先检查并尽早返回,这叫守卫子句。主路径保持扁平,每个拒绝条件也离它产生的原因更近。
def shipping(total, member=False):
if total <= 0:
return "invalid total"
if total >= 50 or member:
return "free shipping"
return "shipping: 5.00"
for total in [0, 42, 50]:
print(total, shipping(total))
print(50, shipping(50, member=True))用提前返回代替嵌套分支
边界值和显式的真假判断
边界值值得单独测试。if total 会把 0 当成假,可能掩盖无效订单;当 0 表示缺失数据时,用 total > 0 更明确。互斥的情况放进同一条 if/elif/else 链。
for total in [0, 49.99, 50]:
if total <= 0:
print(total, "invalid")
elif total < 50:
print(total, "paid shipping")
else:
print(total, "free shipping")测试阈值两侧的值
用守卫语句减少嵌套
层层嵌套会让正常路径很难看清。守卫语句先处理无效输入并立刻返回,后面的代码就能保持扁平。守卫语句适合处理前置条件,不适合隐藏复杂分支。读者应该能从顶部往下扫一眼,就看到一条正常路径。
def shipping(weight):
if weight <= 0:
return "无效"
if weight < 1:
return "小件"
return "标准"
for w in (0, 0.5, 3):
print(w, shipping(w))无效情况提前离开
本课要点
- == 比较值,= 给变量赋值。
- 条件链中只有第一个匹配的分支会执行。
- elif 可以避免匹配后继续检查后面的条件。
- and 要求两边都为真,or 只要求至少一边为真。
- 先处理非法值,守卫子句能让主路径更平。
- 先处理无效输入,正常路径就不用缩进在条件里面。
常见错误
- 把 if score = 90 写成赋值,而不是 if score == 90 进行比较。
- 在 elif 链中把低阈值放在高阈值前面。
- 忘记冒号或缩进代码块。
- 本应互斥的条件写成多个独立 if。
- 把正常路径塞进三层 if 嵌套里。
打印运费提示:订单满 50 元免运费,否则显示运费。
动手试试
改改变量、先预测输出,再运行代码。第一次点击“运行代码”时会下载 Python 运行时,可能需要几秒钟。
练习本课
12 道题,作答后立即看到解释。