# 流程控制
# if
# match-case
用于模式匹配。格式如下:
match <expression> case <pattern>: <block> case <pattern>: <block> ...
- 执行时,会从上到下依次将 expression 与每个 case pattern 比较。如果匹配,则执行该 case block ,并结束 match-case 语句块。
例:
match 1: case 1: # Literal Patterns :如果 pattern 为普通数据类型,则当 expression == pattern 时,视作匹配 pass case 1: # 允许声明重复的 case pattern pass case {1:''}: # Mapping Patterns :如果 pattern 为 dict 类型,则当 pattern 包含于 expression 时,视作匹配 print(1) case x: # Capture Patterns :如果 pattern 为一个标识符,则视作变量,会匹配一个任意值,并赋值(称为 bind )。该变量在 match-case 语句块之后依然存在 print(x) case 1 | 'A': # 可以用 | 连接多个 pattern ,分别尝试匹配 pass case [1, x, y] | (x, y): # 用 | 连接的每个 pattern 中,必须使用相同数量、名称的变量,否则抛出异常:SyntaxError: alternative patterns bind different names pass case 1 as x: # 可以用关键字 as 将匹配结果赋值给一个变量 print(x) case [1, (2 | 3) as x]: pass case [1, x] if x > 0: # 可以添加 if 条件。先判断 case pattern 是否匹配,如果匹配则绑定变量,再判断 if 条件是否成立,如果成立才执行 case block print(x) case [1, *args]: # 支持使用 * 元组参数,匹配任意个值 print(*args) case {1: _, **kwargs}: # pattern 为 dict 类型时,支持使用 ** 字典参数 print(kwargs) case _: # Wildcard Pattern :如果 pattern 只是一个 _ ,则可以匹配任意值,但不会绑定赋值给 _ 。如果 pattern 不止包含 _ ,则当作 Capture Patterns 处理 pass
Class Patterns :如果 pattern 为一个对象,则先比较 expression、pattern 是否属于同一 class ,再比较实参列表是否相同,如果相同才算匹配。
- pattern 不能是一个类名,否则会当作 Capture Patterns 处理。
>>> match 1: ... case str: # 这里会把 expression 赋值给标识符 str ... print(str) ... 1
- 内置类已经实现了
__match_args__
,可以直接匹配。>>> match 1: ... case int(1): ... print(1) ... 1
- 比较实参列表时,字典参数会直接比较,而位置参数会根据
__match_args__
转换成字典参数再比较。>>> class Point: ... __match_args__ = ('x', 'y') ... def __init__(self, x=0, y=0): ... self.x = x ... self.y = y ... >>> >>> match Point(): ... case Point(): ... print(1) ... 1 >>> match Point(1, 2): ... case Point(1, y=2): ... print(1) ... 1
__match_args__
取值为 tuple 类型。如果未定义,则在 case 比较时会抛出异常:TypeError: Point() accepts 0 positional sub-patterns (1 given)
- pattern 不能是一个类名,否则会当作 Capture Patterns 处理。