目 录CONTENT

文章目录

Python(十四) 中的 match-case 模式匹配

Python(十四) 中的 match-case 模式匹配

一、什么是 match-case

match-case 是 Python 3.10 开始加入的一种语法,中文通常叫“模式匹配”。

它的作用是:根据一个值的不同情况,选择执行不同的代码。

从功能上看,match-caseif...elif...else 有些相似,都是用来做分支判断的。

但是 match-case 更适合处理下面这类情况:

一个变量可能有多种固定取值
一个数据结构可能有不同形状
需要根据列表、元组、字典等结构进行判断
代码中有很多 if...elif...elif...

生活化理解:

拿到一个东西,看看它符合哪种情况。
符合第一种,就按第一种处理。
符合第二种,就按第二种处理。
都不符合,就按默认方式处理。

例如:

command = "start"

match command:
    case "start":
        print("开始")
    case "stop":
        print("停止")
    case "pause":
        print("暂停")
    case _:
        print("未知命令")

这段代码的意思是:

如果 command 是 "start",输出“开始”。
如果 command 是 "stop",输出“停止”。
如果 command 是 "pause",输出“暂停”。
如果都不是,输出“未知命令”。

二、match-case 的基本格式

语法格式:

match 要匹配的对象:
    case 模式1:
        模式1匹配成功时执行的代码
    case 模式2:
        模式2匹配成功时执行的代码
    case 模式3:
        模式3匹配成功时执行的代码
    case _:
        前面都不匹配时执行的代码

说明:

match 后面写要判断的对象。
case 后面写匹配规则。
哪个 case 匹配成功,就执行哪个 case 下面的代码。
case _ 表示默认情况,类似 else。

注意:matchcase 后面都要加冒号。

示例:根据星期几输出安排。

day = "周六"

match day:
    case "周一":
        print("上班")
    case "周二":
        print("上班")
    case "周三":
        print("上班")
    case "周四":
        print("上班")
    case "周五":
        print("上班")
    case "周六":
        print("休息")
    case "周日":
        print("休息")
    case _:
        print("输入错误")

三、match-case 和 if-elif-else 的关系

很多简单的 match-case 都可以用 if...elif...else 实现。

例如:

level = "A"

match level:
    case "A":
        print("优秀")
    case "B":
        print("良好")
    case "C":
        print("及格")
    case _:
        print("未知等级")

可以写成:

level = "A"

if level == "A":
    print("优秀")
elif level == "B":
    print("良好")
elif level == "C":
    print("及格")
else:
    print("未知等级")

二者的区别可以这样讲:

if...elif...else 更通用,适合各种条件判断。
match-case 更适合“把一个对象拿来匹配多种情况”。

如果只是判断大小关系,比如:

score = 85

if score >= 90:
    print("优秀")
elif score >= 60:
    print("及格")
else:
    print("不及格")

这种场景使用 if...elif...else 更自然。

如果是判断固定命令、固定状态、固定结构,使用 match-case 会更清楚。

四、字面量模式

字面量模式就是直接匹配具体的值。

常见字面量包括:

数字
字符串
布尔值
None

示例:

status = 404

match status:
    case 200:
        print("请求成功")
    case 404:
        print("页面不存在")
    case 500:
        print("服务器错误")
    case _:
        print("未知状态码")

输出结果:

页面不存在

再看一个字符串示例:

role = "admin"

match role:
    case "admin":
        print("管理员")
    case "teacher":
        print("教师")
    case "student":
        print("学生")
    case _:
        print("普通用户")

五、通配符模式 _

_ 是通配符模式,表示“其他所有情况”。

它类似于 if...elif...else 中的 else

示例:

command = "delete"

match command:
    case "add":
        print("添加数据")
    case "update":
        print("修改数据")
    case "search":
        print("查询数据")
    case _:
        print("无法识别的命令")

这里的 case _: 表示:

如果前面的 case 都没有匹配成功,就执行这里。

教学提醒:

通常建议把 case _ 放在最后。

因为它可以匹配所有情况,如果放在前面,后面的 case 就没有机会执行了。

六、或模式 |

| 表示“或者”,可以让多个值共用同一段代码。

示例:判断是否是周末。

day = "周日"

match day:
    case "周六" | "周日":
        print("周末")
    case "周一" | "周二" | "周三" | "周四" | "周五":
        print("工作日")
    case _:
        print("输入错误")

这里:

case "周六" | "周日":

表示:

如果 day 是 "周六" 或者 "周日",就匹配成功。

这个写法比写多个重复的 case 更简洁。

七、变量捕获模式

case 中,如果直接写一个变量名,它不是在比较变量值,而是在“捕获”匹配到的内容。

这个地方是初学者非常容易出错的。

示例:

value = 10

match value:
    case x:
        print("匹配到的值是:", x)

输出结果:

匹配到的值是: 10

这里的 case x: 会匹配任何值,并把这个值保存到变量 x 中。

也就是说:

case x 不是判断 value 是否等于 x。
case x 是把 value 的值赋给 x。

如果想匹配具体的字符串或数字,要直接写字面量:

match value:
    case 10:
        print("值是 10")

教学提醒:

case 后面直接写普通变量名,会匹配所有内容。
所以不要把它误认为是相等判断。

八、带条件的匹配 guard

case 后面可以加 if 条件,这叫守卫条件,也常叫 guard。

它的作用是:先匹配模式,再判断额外条件。

示例:判断数字正负。

num = 8

match num:
    case x if x > 0:
        print("正数")
    case x if x < 0:
        print("负数")
    case 0:
        print("零")

解释:

case x 会先捕获 num 的值。
if x > 0 再判断这个值是否大于 0。

再看一个成绩示例:

score = 85

match score:
    case x if x >= 90:
        print("优秀")
    case x if x >= 60:
        print("及格")
    case x if x >= 0:
        print("不及格")
    case _:
        print("成绩不合法")

不过要提醒学生:如果主要是比较大小,用 if...elif...else 通常更直观。

九、序列模式

序列模式可以匹配列表、元组等序列结构。

也就是说,match-case 不只能看“值是多少”,还可以看“结构长什么样”。

示例:匹配坐标。

point = (3, 5)

match point:
    case (0, 0):
        print("原点")
    case (0, y):
        print("在 y 轴上,y =", y)
    case (x, 0):
        print("在 x 轴上,x =", x)
    case (x, y):
        print("普通点,x =", x, "y =", y)

输出结果:

普通点,x = 3 y = 5

解释:

case (0, 0) 匹配坐标是原点。
case (0, y) 匹配第一个值是 0 的坐标,并捕获第二个值。
case (x, 0) 匹配第二个值是 0 的坐标,并捕获第一个值。
case (x, y) 匹配两个元素的坐标,并捕获两个值。

星号 * 的使用

序列模式中可以使用 * 捕获多个元素。

示例:

data = [1, 2, 3, 4]

match data:
    case [first, *middle, last]:
        print("第一个:", first)
        print("中间:", middle)
        print("最后一个:", last)

输出结果:

第一个: 1
中间: [2, 3]
最后一个: 4

这里:

first 捕获第一个元素
middle 捕获中间多个元素
last 捕获最后一个元素

十、字典模式

字典模式可以根据字典中的键和值进行匹配。

示例:处理用户信息。

user = {"name": "小明", "role": "student"}

match user:
    case {"role": "admin"}:
        print("管理员用户")
    case {"role": "teacher"}:
        print("教师用户")
    case {"role": "student", "name": name}:
        print("学生:", name)
    case _:
        print("未知用户")

输出结果:

学生: 小明

解释:

case {"role": "student", "name": name}
表示匹配 role 是 "student",并把 name 对应的值保存到变量 name 中。

注意:

字典模式通常只要求匹配指定的键。
字典里有其他键,一般不影响匹配。

示例:

user = {"name": "小红", "role": "student", "age": 18}

match user:
    case {"role": "student"}:
        print("这是学生")

虽然字典中还有 nameage,但因为 role 匹配成功,所以会输出:

这是学生

十一、类模式

match-case 也可以匹配对象。

初学阶段可以简单了解,不必讲得太深。

示例:

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

person = Student("小明", 18)

match person:
    case Student(name=name, age=age):
        print("学生姓名:", name)
        print("学生年龄:", age)
    case _:
        print("不是学生对象")

输出结果:

学生姓名: 小明
学生年龄: 18

解释:

case Student(name=name, age=age)
表示匹配 Student 类型的对象,并取出它的 name 和 age 属性。

如果当前课程还没有讲类,可以先跳过这一节。

十二、匹配顺序很重要

match-case 会从上往下依次匹配。

一旦某个 case 匹配成功,后面的 case 就不会再判断。

示例:

command = "start"

match command:
    case _:
        print("默认处理")
    case "start":
        print("开始")

这段代码有问题,因为 case _: 可以匹配所有情况。

所以会输出:

默认处理

后面的 case "start": 永远不会执行。

正确写法:

command = "start"

match command:
    case "start":
        print("开始")
    case _:
        print("默认处理")

教学提醒:

更具体的 case 写在前面。
默认情况 case _ 写在最后。

十三、常见注意事项

1. Python 版本必须是 3.10 或更高

match-case 是 Python 3.10 才加入的语法。

如果使用 Python 3.9 或更早版本,会报语法错误。

可以用下面的代码查看 Python 版本:

import sys

print(sys.version)

2. match 和 case 后面都要加冒号

错误写法:

match command
    case "start"
        print("开始")

正确写法:

match command:
    case "start":
        print("开始")

3. case 下方代码要正确缩进

正确写法:

match command:
    case "start":
        print("开始")

错误写法:

match command:
case "start":
print("开始")

Python 使用缩进表示代码块,通常使用 4 个空格作为一级缩进。

4. case _ 通常放在最后

case _: 表示默认匹配,可以匹配所有没有被前面处理的情况。

如果放在前面,后面的 case 通常就没有意义了。

推荐写法:

match value:
    case 1:
        print("一")
    case 2:
        print("二")
    case _:
        print("其他")

5. case x 不是判断是否等于变量 x

这是 match-case 中非常重要的易错点。

示例:

x = 10
value = 20

match value:
    case x:
        print("匹配成功,x =", x)

输出结果:

匹配成功,x = 20

原因:

case x 会捕获 value 的值,并把它赋给 x。
它不是判断 value 是否等于原来的 x。

如果要判断固定值,直接写固定值:

match value:
    case 10:
        print("值是 10")

如果要用条件判断变量之间是否相等,可以使用 guard:

x = 10
value = 20

match value:
    case y if y == x:
        print("value 等于 x")
    case _:
        print("value 不等于 x")

6. 不要把 match-case 当成所有 if 的替代品

match-case 很有用,但不是所有情况都适合用它。

适合使用 if...elif...else 的情况:

判断大小关系
判断多个复杂条件
条件之间不是围绕同一个对象展开

适合使用 match-case 的情况:

根据一个对象的不同取值进行处理
根据列表、元组、字典等结构进行处理
命令分发、状态判断、数据解析

7. 注意不要写过于复杂的模式

match-case 可以写得很强大,但如果模式太复杂,学生会看不懂。

教学阶段建议先掌握:

字面量模式
通配符 _
或模式 |
guard 条件
序列模式
字典模式

类模式可以作为拓展内容。

十四、课堂示例

示例 1:命令菜单

command = input("请输入命令 add/delete/search:")

match command:
    case "add":
        print("执行添加功能")
    case "delete":
        print("执行删除功能")
    case "search":
        print("执行查询功能")
    case _:
        print("未知命令")

讲解重点:

match command 表示要匹配 command 的值。
不同的 case 对应不同命令。
case _ 处理未知命令。

示例 2:HTTP 状态码

status = 200

match status:
    case 200:
        print("成功")
    case 400:
        print("请求错误")
    case 404:
        print("资源不存在")
    case 500:
        print("服务器错误")
    case _:
        print("未知状态")

这个例子适合讲解字面量模式。

示例 3:根据坐标判断位置

point = (0, 5)

match point:
    case (0, 0):
        print("原点")
    case (0, y):
        print("在 y 轴上,y =", y)
    case (x, 0):
        print("在 x 轴上,x =", x)
    case (x, y):
        print("普通点,x =", x, "y =", y)

这个例子适合讲解序列模式和变量捕获。

示例 4:处理字典数据

message = {"type": "text", "content": "你好"}

match message:
    case {"type": "text", "content": content}:
        print("文本消息:", content)
    case {"type": "image", "url": url}:
        print("图片地址:", url)
    case {"type": "video", "url": url}:
        print("视频地址:", url)
    case _:
        print("未知消息类型")

这个例子适合讲解字典模式,也比较接近真实开发中的数据处理。

十五、课堂练习

练习 1:判断季节

要求:输入季节名称,输出对应提示。

参考代码:

season = input("请输入季节:")

match season:
    case "春天":
        print("万物复苏")
    case "夏天":
        print("天气炎热")
    case "秋天":
        print("秋高气爽")
    case "冬天":
        print("天气寒冷")
    case _:
        print("输入错误")

练习 2:简单计算器

要求:根据运算符执行加减乘除。

参考代码:

a = 10
b = 5
op = "+"

match op:
    case "+":
        print(a + b)
    case "-":
        print(a - b)
    case "*":
        print(a * b)
    case "/":
        print(a / b)
    case _:
        print("不支持的运算符")

练习 3:判断坐标位置

要求:根据坐标判断在原点、x 轴、y 轴还是普通位置。

参考代码:

point = (3, 0)

match point:
    case (0, 0):
        print("原点")
    case (x, 0):
        print("在 x 轴上")
    case (0, y):
        print("在 y 轴上")
    case (x, y):
        print("普通点")

练习 4:处理用户角色

要求:根据用户字典中的角色输出不同信息。

参考代码:

user = {"name": "小明", "role": "teacher"}

match user:
    case {"role": "admin", "name": name}:
        print(name, "是管理员")
    case {"role": "teacher", "name": name}:
        print(name, "是教师")
    case {"role": "student", "name": name}:
        print(name, "是学生")
    case _:
        print("未知用户")

十六、教学建议

讲解 match-case 时,可以按照下面顺序:

1. 先复习 if...elif...else
2. 说明 match-case 也是做多分支判断
3. 用命令菜单或状态码引入基本语法
4. 讲 case _ 相当于默认情况
5. 讲 | 可以合并多个匹配值
6. 再讲序列模式和字典模式
7. 最后强调变量捕获这个易错点

可以用下面的问题引导学生:

如果一个命令有很多种取值,用很多 elif 会不会太长?
如果一个坐标是 (0, 5),能不能直接判断它在 y 轴上?
如果一个字典表示消息,能不能根据 type 字段选择不同处理方式?
case x 到底是判断 x,还是把值赋给 x?

教学重点建议放在:

基本语法
case _
或模式 |
变量捕获
序列模式
字典模式
匹配顺序

十七、总结

match-case 是 Python 中用于模式匹配的语法。

它可以根据一个对象的不同值或不同结构,选择执行不同代码。

可以这样记:

match:拿出一个对象来匹配
case:列出一种可能的情况
case _:其他所有情况
|:表示或者
case x:捕获值,不是比较变量

match-case 适合:

命令分发
状态判断
处理列表、元组、字典等结构化数据
替代过长的 if...elif...elif...

需要注意:

1. Python 版本必须是 3.10 或更高
2. match 和 case 后面都要加冒号
3. case _ 通常放在最后
4. 匹配顺序从上到下
5. case x 是变量捕获,不是相等判断
6. 不要把 match-case 当成所有 if 的替代品

一句话总结:

match-case 让程序可以根据“值是什么”或“结构长什么样”来选择不同处理方式,特别适合处理多种固定情况和结构化数据。
0
博主关闭了当前页面的评论