Python 中的结构模式匹配
Python 3.10 引入了一项备受期待的新特性——结构模式匹配(Structural Pattern Matching),这通过 PEP 634、PEP 635 和 PEP 636 正式成为 Python 语法的一部分。它不仅让代码更加清晰易读,还极大地简化了处理复杂数据结构的流程。本文将深入探讨 Python 中结构模式匹配的用法及其背后的核心概念。
一、基本语法:match 与 case
结构模式匹配的核心由 match 和 case 两个关键字组成。从表面上看,它类似于 C 或 Java 中的 switch-case 语句,但 Python 的模式匹配远不止于此,它不仅匹配值,还能解构数据形状。
def http_status(status): match status: case 200: return "OK" case 404: return "Not Found" case 500: return "Internal Server Error" case _: return "Unknown Status"
在上面的例子中,_ 是通配符,当所有其他 case 都不匹配时,它会捕获剩余的所有情况,类似于传统 switch 中的 default。
二、字面量模式
字面量模式是最简单的匹配形式,可以匹配数字、字符串、布尔值和 None。
def handle_command(command):
match command:
case "quit":
print("Exiting...")
case "reset":
print("Resetting...")
case _:
print("Unknown command")三、捕获模式与变量绑定
捕获模式允许我们将匹配到的值绑定到一个变量上,以便在 case 块中使用。即使匹配的是简单的数据,变量绑定也能让代码更具表达力。
def process_point(point):
match point:
case (x, y):
print(f"Point at x={x}, y={y}")
case _:
print("Not a point")四、序列模式
序列模式可以匹配列表或元组,并支持解构。你可以使用 _ 忽略某些元素,也可以使用 * 运算符匹配可变长度的部分。
def handle_list(items):
match items:
case []:
print("Empty list")
case [first]:
print(f"Only one item: {first}")
case [first, *rest]:
print(f"First: {first}, Rest: {rest}")五、映射模式
映射模式用于匹配字典。它只检查指定的键是否存在并匹配对应的值,而忽略字典中其他的键值对。
def process_config(config):
match config:
case {"host": host, "port": port}:
print(f"Connecting to {host}:{port}")
case {"host": host}:
print(f"Connecting to {host} with default port")
case _:
print("Invalid configuration")六、类模式
类模式允许我们匹配对象的属性。默认情况下,它按位置匹配属性(类似于构造函数的参数顺序),也可以按关键字匹配,这大大增强了代码的可读性。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def handle_point(pt):
match pt:
case Point(x=0, y=0):
print("Origin")
case Point(x=x, y=0):
print(f"On X axis at {x}")
case Point(x=0, y=y):
print(f"On Y axis at {y}")
case Point(x=x, y=y):
print(f"Point at {x}, {y}")七、OR 模式
使用 | 运算符可以在同一个 case 中匹配多种模式。如果多种模式需要执行相同的逻辑,这能避免代码重复。
def handle_direction(direction):
match direction:
case "up" | "down":
print("Vertical movement")
case "left" | "right":
print("Horizontal movement")八、守卫子句(Guard Clauses)
可以在 case 语句后添加 if 条件,称为守卫子句。只有当模式匹配成功且守卫条件为真时,才会执行该 case 块。
def categorize_number(num):
match num:
case x if x < 0:
print("Negative")
case x if x == 0:
print("Zero")
case x:
print("Positive")九、嵌套模式
模式可以嵌套使用,以处理复杂的数据结构。这使得我们能够精确地描述深层嵌套的数据形状。
def handle_nested(data):
match data:
case {"type": "point", "coords": (0, 0)}:
print("Origin point")
case {"type": "point", "coords": (x, y)}:
print(f"Point at {x}, {y}")
case _:
print("Unknown data structure")十、实战示例:处理 API 响应
假设我们正在处理来自某个第三方 API 的响应数据,结构模式匹配可以优雅地处理各种返回情况。以下示例中,我们将请求地址设为 www.ipipp.com。
import requests
def fetch_data(endpoint):
response = requests.get(f"http://www.ipipp.com/api/{endpoint}")
match response.status_code, response.json():
case 200, {"status": "success", "data": data}:
return data
case 200, {"status": "error", "message": msg}:
raise ValueError(f"API Error: {msg}")
case 404, _:
raise FileNotFoundError("Resource not found")
case code, _:
raise Exception(f"Unexpected HTTP {code}")总结
Python 的结构模式匹配是一个强大而灵活的工具,它使得处理复杂数据结构变得直观和声明式。通过字面量、捕获、序列、映射、类模式以及守卫子句的组合,开发者可以编写出更加健壮和可读的代码。虽然对于初学者来说,掌握各种模式需要一定的学习曲线,但一旦熟练运用,它将成为你 Python 编程工具箱中不可或缺的利器。