Structural Pattern Matching: 翻译过来应该是 结构化的模式匹配。从python 3.10开始提供了match statement。它远比简单的其它语言中的那种switch语句功能强大的多。
通过一个例子来了解一下这种语句的用法。
假设我们有一个函数,用来区分用户做的操作,并将其打印出来。 我们使用json结构的字符串来做为用户操作的内容并传到这个函数中。目前这个函数只区分用户敲击键盘,及单击鼠标。
下面的函数内部使用if else语句来判断输入的json字符串应该匹配到哪一种用户操作。判断的条件足够的严谨!
import json
def log(event):
parsed_event = json.loads(event)
if (
"keyboard" in parsed_event and
"key" in parsed_event["keyboard"] and
"code" in parsed_event["keyboard"]["key"]
):
code = parsed_event["keyboard"]["key"]["code"]
print(f"Key pressed: {code}")
elif (
"mouse" in parsed_event and
"cursor" in parsed_event["mouse"] and
"screen" in parsed_event["mouse"]["cursor"]
):
screen = parsed_event["mouse"]["cursor"]["screen"]
if isinstance(screen, list) and len(screen) == 2:
x, y = screen
print(f"Mouse cursor: x={x}, y={y}")
else:
print("Unknown event type")
else:
print("Unknown event type")
event1 = '''{"keyboard": {"key": {"code": "Enter"}}}'''
event2 = '''{"mouse": {"cursor": {"screen": [600, 900]}}}'''
event3 = '''{"mouse": {"click": {"screen": [600, 900]}}}'''
log(event1) # Key pressed: Enter
log(event2) # Mouse cursor: x=600, y=900
log(event3) # Unknown event type
让我们看一下如果我们使用match statement,如何来改写上面的函数:
import json
def log(event):
match json.loads(event):
case {"keyboard": {"key": {"code": code}}}:
print(f"Key pressed: {code}")
case {"mouse": {"cursor": {"screen": [x, y]}}}:
print(f"Mouse cursor: {x=}, {y=}")
case _:
print("Unknown event type")
event1 = '''{"keyboard": {"key": {"code": "Enter"}}}'''
event2 = '''{"mouse": {"cursor": {"screen": [600, 900]}}}'''
event3 = '''{"mouse": {"click": {"screen": [600, 900]}}}'''
log(event1) # Key pressed: Enter
log(event2) # Mouse cursor: x=600, y=900
log(event3) # Unknown event type
我们可以明显的看到,实现了同样的判断逻辑,我们使用match语句后,代码非常精简,并且更直观易读。
上面的示例体现了match语句用于匹配数据字典格式数据的能力,就想在场明一个字典的结构以及它要有的某些key和value,并且还可以把我们感兴趣的部分数据方便的提取出来。
现在,假设我们要用一个列表中包含三个值,来表示空间坐标系中的一个点,这个点必须在z轴上,也就是第三个数字为0。 前两个数字可以是float,也可以是int。
下面我们用传统的if...else语句来做一个逻辑严谨的匹配规则判断:
# subject = ['a'] # 匹配不上
# subject = [9.3, 10, 0, 88] # 匹配不上
subject = [9.3, 10, 0] # 匹配成功
if isinstance(subject, list) and len(subject) == 3:
if (
isinstance(subject[0], int | float) and
isinstance(subject[1], int | float) and
subject[2] == 0
):
x, y, _ = subject
print(f"Point({x=}, {y=})")
# 输出: Point(x=9.3, y=10)
接下来我们用match语句来实现上述匹配规则:
# subject = ['a'] # 匹配不上
# subject = [9.3, 10, 0, 88] # 匹配不上
subject = [9.3, 10, 0] # 匹配成功
match subject:
case list([int() | float() as x, int() | float() as y, 0]):
print(f"Point({x=}, {y=})")
# 输出: Point(x=9.3, y=10)
标签:code,Pattern,screen,event,cursor,Matching,match,subject
From: https://www.cnblogs.com/rolandhe/p/18660534