没有 `break` 的 `switch`,反而更好用了?
如果你从 C 语言或 Java 转过来写 Python,第一次见到 match-case 时,可能会下意识地找 break 在哪。找了一圈没找到,然后心里一紧:这玩意儿会不会“穿透”啊?
放心,Python 的 match-case 不需要 break,它匹配完一个分支就自动退出。这个设计让多路选择代码变得更干净,也更符合直觉。
自助餐模式:端着变量去“打菜”
想象你走进一家自助餐厅,手里端着一个盘子——这个盘子就是你要匹配的变量。餐厅里有一排摊位,每个摊位前面立着牌子,写着对应的菜品编号:
case "A1": 薯片
case "A2": 巧克力
case "A3": 可乐
case _: 无效按钮
你端着 "A2" 走到第一个摊位,厨师看了一眼,不对,不是 A1。再走到第二个摊位,对了,是 A2,厨师给你打了一勺巧克力,然后你就端着盘子走了——不会再去 A3 摊位问“能不能再来点可乐”。
这就是 match-case 的执行逻辑:从上到下逐个匹配,一旦命中,执行对应代码块,然后整段 match 结束。
button = "A2"
match button:
case "A1":
print("出货:薯片")
case "A2":
print("出货:巧克力")
case _:
print("无效按钮")
输出:出货:巧克力。
_ 不是变量名,是“万能通行证”
很多初学者会把 case _ 理解成“else”,然后问:那 _ 能不能放在中间?语法上可以,但逻辑上等于给自己挖坑。
来看这道题:
x = 1
match x:
case 0:
print("零")
case 1:
print("一")
case _:
print("其他")
输出是什么?显然是 一。因为 case 1 命中了,后面的 _ 根本轮不到。
但如果把 _ 提到前面:
match x:
case _:
print("其他")
case 1:
print("一")
那 case 1 永远不可能执行。_ 能匹配任何值,它前面的变量全都会被它截胡。所以,语法上 _ 可以出现在任何位置,但聪明人都把它放在最后。
| 或匹配:给自助餐加个套餐
有时候好几个选项要执行同样的操作,比如判断一个颜色是不是三原色。如果写三个一模一样的 case,那代码就太啰嗦了。match-case 支持用竖线 | 把多个值连起来:
color = "red"
match color:
case "red" | "yellow" | "blue":
print("这是三原色之一")
case _:
print("其他颜色")
一行搞定三种情况。这个语法特别适合那种“多个输入,一个动作”的场景,比如判断用户输入的命令是不是退出指令:
case "quit" | "exit" | "q":
print("再见")
别踩的四个坑
- 忘写冒号:
case 1后面必须有:,跟if一样。 - 缩进错位:
match和case对齐,case下面的代码要再缩进一层。 - 把
_写成变量:_是通配符,不是普通变量名,别想着用它来接收值。 - Python 版本不够:3.10 以下跑不了,会报
SyntaxError。如果还在用 3.8、3.9,要么升级,要么老老实实用if-elif-else。
什么时候别用 match-case
match-case 很强,但它只能做等值匹配。如果你想判断 x > 5,或者 x % 2 == 0,那还得用 if。别为了显摆新语法而硬用,代码的可读性永远排第一。
举个反面例子:
# 这样写就太别扭了
match x:
case _ if x > 5:
print("大于5")
case _:
print("小于等于5")
虽然 match-case 支持守卫条件,但对这种简单的比较,if-else 两行就搞定了,何必绕弯子。
顺手看一道判断题
之前看到有同学争论:“下划线 _ 只能放在最后一个 case 作为默认匹配。”这个说法对不对?答案是——不对。
_ 不是 switch 里的 default,它只是一个普通的通配符模式,语法上可以放在任何位置。但放在非末尾会导致后面的 case 永远不可达,所以规范上强烈建议放最后。这道题的考点其实是在区分“语法允许”和“写法合理”,概念搞清楚了,这种题就不会错。
进阶方向
如果你觉得 match-case 只是 switch 的替代品,那你就低估它了。它真正的威力在于结构模式匹配,比如匹配列表、元组、字典,甚至自定义类的属性:
point = (3, 0)
match point:
case (0, 0):
print("原点")
case (x, 0):
print(f"x轴上的点,x={x}")
case (0, y):
print(f"y轴上的点,y={y}")
case (x, y):
print(f"普通点:({x}, {y})")
这种能力远超传统的 switch,在做数据解析、命令分发、AST 处理时特别有用。学到这里,才算真正走进了 Python 模式匹配的大门。
关于作者
我是赵老师,持有 NOI 信息学奥赛教练证书,拥有 15 年以上的软件开发经验,从事信息学少儿编程教学已有 8 年时间。
这些年累计帮助 多名 学生通过编程特长升入自己心仪的目标学校。
如果你在编程学习上有任何疑问,欢迎联系我:18620372957(微信同号)