Python-Match(结构化模式匹配)

文章目录
  1. 1. 替换switch
  2. 2. 扩展switch- 结构化模式匹配
    1. 2.1. 匹配列表模式
    2. 2.2. 匹配 class模式
    3. 2.3. 匹配字典

Python3.10引入了类似于C-switch的语法:Match。更准确的是structure pattern matching

替换switch

之前,Python要实现类似于switch的功能需要使用if-else的语法。比如

1
2
3
4
5
6
7
code = 1
if code == 1:
# do something
elif code === 2:
# do another thing
else:
# rest thing

这种代码一直为人所诟病,认为这种代码没有直观地展示代码的功能。现在要实现类switch的功能,可以这样写

1
2
3
4
5
6
7
8
code = 1
match code:
case 1:
# do something
case 2:
# do another thing
case _:
# rest thing

扩展switch- 结构化模式匹配

Structure-Pattern-Matching(结构化模式匹配)使得匹配对象不局限于值,还可以匹配结构模式,也即是待匹配的对象是否符合我们给出的模式。请看例子

匹配列表模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def command_split(command):
match command.split():
case ["make"]:
print("default make")
case ["make", cmd]:
# 这里有新变量cmd,case语句会将第二部分的任何对象绑定到cmd变量上(注意不是assign)
print(f"make command found: {cmd}")
case ["restart"]:
print("restarting")
case ["rm", *files]:
# files: list
print(f"deleting files: {files}")
case _:
print("didn't match")
1
2
3
4
5
6
7
def match_alternatives(command):
match command.split():
case ["north"] | ["go", "north"]:
# | represents 'or'
print("going north")
case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]:
print(f"picking up: {obj}")
1
2
3
4
5
# 子模式-模式可以嵌套
def match_capture_subpattern(command):
match command.split():
case ["go", ("north" | "south" | "east" | "west") as direction]:
print(f"going {direction}")
1
2
3
4
5
6
7
# go only for "allowable direction"
def match_guard(command, exits):
match command.split():
case ["go", direction] if direction in exits:
print(f"going {direction}")
case ["go", _]:
print(f"can't go that way")

匹配 class模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@dataclass
class Click:
position: tuple[int, int]
button: str

@dataclass
class KeyPress:
key_name: str

@dataclass
class Quit:
pass

def match_by_class(event):
match event:
case Click(position=(x,y), button="left"):
# is `Click` intance? with attr `button=left`?
# and position is a tuple?
# 不会构建一个intance.
print(f"handling left click at {x,y}")
case Click(position=(x,y)):
print(f"handling other click at {x,y}")
case KeyPress("Q"|"q") | Quit():
print("quitting")
case KeyPress(key_name="up arrow"):
print("going up")
case KeyPress():
pass #ignore other keystrokes
case other_event:
raise ValueError(f'unrecognized event: {other_event}')

匹配字典

1
2
3
4
5
6
7
8
9
10
def match_json_event(event):
match event:
case {"transport": "http"}:
# 是否有一个key:value组合为上述内容
print("insecure event ignored")
case {"verb": "GET", "page": "articles", "pageno": n}:
# "pageno"是否出现?出现的话,把值赋给n
print(f"let me get that article for you on page {n}...")
case {"verb": "POST", "page": "signup"}:
print("handling signup")

内容来自于以下视频,添加了注释、内容:

  1. The Hottest New Feature Coming In Python 3.10 - Structural Pattern Matching / Match Statement