☰
Python编写条件分支代码方法
2026/10/10 20:31:36 网站建设 项目流程

前言


「写条件分支」看起来是最没技术含量的活,但代码质量的分水岭恰恰在这里。同一个业务规则,有人写出五层嵌套的if,有人用三行if/elif加一个字典就清爽收尾。区别不在于聪明,而在于是否知道 Python 提供了哪些分支写法、各自适合什么场景。


初学者最常见的三个误解是:以为and/or返回的是True/False(其实返回的是参与运算的操作数本身);以为match就是 C 的switch(其实没有贯穿、还能匹配结构);以及以为x or default是安全的默认值写法(当x是0或空字符串时会被错误替换)。


本文按「从简单到复杂」的顺序讲六种条件分支写法,并给出各自该在什么时候用。文中的match语句需要 Python 3.10 及以上,其余写法在 Python 3.8 及以上都能跑。


一、基础:if / elif / else


最直接的写法。要点是命中即停,所以判断顺序就是优先级顺序。


# 适用于 Python 3 全版本
def http_status_text(code):
if code == 200:
return "OK"
elif code == 301:
return "Moved Permanently"
elif code == 404:
return "Not Found"
elif 500 <= code < 600:
return "Server Error"
else:
return "Unknown"

这里用到了链式比较500 <= code < 600,它等价于500 <= code and code < 600,但更短也更不易写错。


二、条件表达式(三元运算符)


当分支只是为了「二选一取值」时,用条件表达式比写四行if/else更清晰:


# 适用于 Python 3 全版本
age = 17
label = "成年" if age >= 18 else "未成年"
print(label) # 未成年

形式是「真值 if 条件 else 假值」,顺序和 C 的条件 ? 真值 : 假值相反,这是高频写错点。它适合短表达式,嵌套多层会立刻变得难读:


# 适用于 Python 3 全版本
# 不推荐:嵌套三元,可读性差
grade = "A" if s >= 90 else ("B" if s >= 80 else "C")

多层判断还是回到if/elif/else。


三、布尔运算的短路与返回值


and和or有短路特性,而且返回的是操作数本身:



  • a or b:a为真就返回a,否则返回b

  • a and b:a为假就返回a,否则返回b


# 适用于 Python 3 全版本
print(0 or "默认") # 默认
print("x" or "默认") # x
print(0 and 1 / 0) # 0(右侧未求值,不会除零)
print("abc" and 42) # 42

利用返回值可以写出简短的默认值逻辑,但要注意假值判断的陷阱:or会把0、""、[]也当成「没有值」。如果一个合法值就是0,必须改用显式的is None判断:


# 适用于 Python 3 全版本
def with_default(value, default=100):
# 错误示范:value 为 0 时也会被替换
# return value or default

# 正确:只在确实是 None 时才用默认值
return default if value is None else value

print(with_default(0)) # 0
print(with_default(None)) # 100

四、卫语句(提前返回)消除嵌套


深层嵌套的根因通常是「所有失败情况都往里缩进」。反过来写:不合格的输入提前 return,把主逻辑留在最外层。


# 适用于 Python 3 全版本

# 不推荐:嵌套三层
def price_bad(user, item):
if user is not None:
if user.is_active:
if item.stock > 0:
return item.price
else:
return -1
else:
return -2
else:
return -3

# 推荐:卫语句提前返回
def price_good(user, item):
if user is None:
return -3
if not user.is_active:
return -2
if item.stock <= 0:
return -1
return item.price

五、字典分派:把「值相等」的分支换成查表


当分支条件是「某个值和一批常量逐个比较」时,用字典把「动作」或「结果」映射起来,比一长串elif更好维护。


# 适用于 Python 3 全版本
def apply_op(op, a, b):
operations = {
"+": lambda x, y: x + y,
"-": lambda x, y: x - y,
"*": lambda x, y: x * y,
}
func = operations.get(op)
if func is None:
raise ValueError(f"不支持的运算符:{op}")
return func(a, b)

print(apply_op("*", 6, 7)) # 42

注意用.get()而不是operations[op]:直接下标在没有该键时会抛KeyError,除非这正是你想要的错误。字典分派的前提是分派键是可哈希且可比较的常量,不适合范围判断。


六、match 语句:结构化模式匹配(Python 3.10+)


从 Python 3.10 起,语言引入了match/case(PEP 634)。它不是switch的翻版:



  • 没有贯穿(fall-through),命中一个case就结束

  • 能匹配结构(序列、映射、类实例),不只是值

  • _是通配符,相当于默认分支

  • 支持守卫子句case ... if 条件:


# 适用于 Python 3.10+
def describe(command):
match command.split():
case ["go", direction]:
return f"向 {direction} 前进"
case ["look"]:
return "你环顾四周"
case ["take", item] if len(item) > 3:
return f"拿起一个较长的物品:{item}"
case ["take", item]:
return f"拿起 {item}"
case _:
return "无法识别的指令"

print(describe("go north")) # 向 north 前进
print(describe("take")) # 无法识别的指令

需要在 Python 3.10 以下运行时,同一段逻辑只能用if/elif判断len(parts)和各位置的值来手写。


实战:把六种写法用在一个「评分系统」里


# 适用于 Python 3.10+
from dataclasses import dataclass

@dataclass
class Submission:
author: str
score: int | None = None # 3.10+ 的联合类型写法


def grade_of(score):
if score is None:
return "未评分"
if score >= 90:
return "A"
if score >= 80:
return "B"
if score >= 60:
return "C"
return "D"


def label(submission):
if submission.score is None:
return f"{submission.author}:待评分"
status = "优秀" if submission.score >= 90 else "已评分"
return f"{submission.author}:{grade_of(submission.score)}({status})"


def main():
subs = [
Submission("Ada", 95),
Submission("Bob", 72),
Submission("Cy", None),
]
for s in subs:
print(label(s))


if __name__ == "__main__":
main()

输出依次是Ada:A(优秀)、Bob:C(已评分)、Cy:待评分。


注意int | None这种联合类型写法需要 Python 3.10 及以上;在 3.9 里要写typing.Optional[int],3.8 同理。


常见坑点



  1. =与==混淆


❌if code = 200:✅if code == 200:;Python 3 里=用在条件位置是语法错误



  1. 以为and/or返回布尔值


❌ 用x and y的结果去做is True判断 ✅ 它们返回操作数本身,"a" and "b"得到"b",不是True



  1. 用or提供默认值,把合法假值也替换掉


❌return value or default,当value是0/""/[]时误用默认值 ✅return default if value is None else value



  1. 把match当switch用


❌ 期待case会像 C 那样向下贯穿,或以为它只比常量 ✅match无贯穿、能做结构匹配、_是通配符;需要 Python 3.10+



  1. 字典分派时直接用下标导致KeyError


❌operations[op](a, b)✅ 先func = operations.get(op),判空后再调用,或明确用 try/except 捕获



  1. 深层嵌套而不使用卫语句


❌ 把失败分支一层层缩进到看不见主逻辑 ✅ 不合格输入提前return,主逻辑留在最外层



  1. 把范围判断写进字典分派


❌ 试图用{range(0, 60): "D", range(60, 80): "C"}直接查表 ✅range对象相等比较不是区间匹配;范围判断仍用if/elif或专门的区间表



  1. 条件表达式顺序写反


❌label = "未成年" if age >= 18 else "成年"✅ 真值在前:label = "成年" if age >= 18 else "未成年"


总结




写法适用场景注意事项



if/elif/else通用分支、范围判断命中即停,顺序即优先级

条件表达式二选一取值真值在前,勿嵌套多层

and/or短路简单默认值、守卫返回操作数;假值会误触发

卫语句消除深层嵌套失败提前返回

字典分派常量到结果的映射用.get()防KeyError

match结构匹配3.10+,无贯穿,_为通配符



判断该用哪种写法,只需要问自己两个问题:分支条件是「值相等」还是「范围/结构」?值是常量就考虑字典分派,是结构就用match,是范围就用if/elif。至于嵌套过深,先想到卫语句,而不是继续往里缩进。




需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询