Python 结构化模式匹配完全指南(match-case)

Python 3.10 引入结构化模式匹配:match-case 语法处理字面量、序列、字典、类实例与守卫条件,替代冗长的 if-elif 链。本文系统讲解用法与最佳实践。

最佳实践
并发任务的多路径协同插画

直接回答:结构化模式匹配(match-case)让"根据数据的形状分支处理"变得声明式:不仅匹配值,还能解构序列、字典、对象并顺带绑定变量——长的 if-elif 链从此有了优雅的替代。

基本语法

def http_status(code):
    match code:
        case 200:
            return "成功"
        case 404:
            return "页面不存在"
        case 500 | 502 | 503:          # 多值或
            return "服务器错误"
        case _:                         # 通配兜底
            return "未知状态"

| 表示"或"(注意不是 or),_ 是兜底通配——忘了兜底且没匹配上时,静默什么都不做(不报错),这是新手最常见的意外。

按类型匹配

from dataclasses import dataclass

@dataclass
class Point:
    x: float
    y: float

def area(shape):
    match shape:
        case int() | float() as n:      # 匹配数值并绑定为 n
            return n * n
        case str():
            return "字符串没有面积"
        case Point(x=0, y=0):           # 类实例 + 属性匹配
            return 0
        case Point(x=x, y=y):           # 解构属性
            return abs(x * y)

类型检查 + 属性解构一步到位,以前要 isinstance + 属性访问两道工序。

序列解构

for command in commands:  # commands、move、pick 由命令处理模块提供
    match command.split():
        case ["quit"]:
            break
        case ["go", direction]:
            move(direction)
        case ["pick", *items]:
            for item in items:
                pick(item)
        case ["drop", *rest] if len(rest) > 3:
            print("一次最多丢 3 个")

*rest 收集剩余元素,if 守卫加任意条件——适合表达命令结构。序列模式不匹配任意迭代器,也不会把字符串本身拆成字符序列匹配。

字典匹配

match event:
    case {"type": "click", "x": x, "y": y}:
        handle_click(x, y)
    case {"type": "key", "key": "Enter"}:
        submit()
    case {"type": str() as t}:
        print(f"未处理的事件: {t}")

字典匹配是部分匹配:只要声明的键存在且值吻合即命中,多余键不影响——处理 JSON 事件的理想工具。

什么时候不用 match

  • 简单两三分支:if-else 更直白;
  • 需要复杂布尔逻辑:守卫能写但可读性差,不如 if;
  • 按值查表:dict.get() 一行的事别动用 match。

match 的甜区是**"数据结构驱动"的分支**——事件、消息、AST、命令分发。

常见问题(FAQ)

Q:case 里的名字是赋值还是比较?
A:裸名字是绑定(赋值给新变量),不是比较!要比较常量必须带点号(Color.RED)或先用字面量。case RED: 里的 RED 会变成新变量——这是 match 最大的坑。

Q:match 和 if-elif 性能有差吗?
A:不存在普遍适用的性能优胜结论。先按可读性选择,热点再以真实输入基准比较。

Q:能匹配自定义类吗?
A:能,按属性匹配;类里定义 __match_args__ 还能支持位置式匹配(case Point(0, 0))。

官方参考

本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台