模式匹配
当我们用if ... elif ... elif ... else ...
判断时,会写很长一串代码,可读性较差。
如果要针对某个变量匹配若干种情况,可以使用match
语句。
例如,某个学生的成绩只能是A
、B
、C
,用if
语句编写如下:
score = 'B'
if score == 'A':
print('score is A.')
elif score == 'B':
print('score is B.')
elif score == 'C':
print('score is C.')
else:
print('invalid score.')
如果用match
语句改写,则改写如下:
score = 'B'
match score:
case 'A':
print('score is A.')
case 'B':
print('score is B.')
case 'C':
print('score is C.')
case _: # _表示匹配到其他任何情况
print('score is ???.')
使用match
语句时,我们依次用case xxx
匹配,并且可以在最后(且仅能在最后)加一个case _
表示“任意值”,代码较if ... elif ... else ...
更易读。
复杂匹配
match
语句除了可以匹配简单的单个值外,还可以匹配多个值、匹配一定范围,并且把匹配后的值绑定到变量:
age = 15
match age:
case x if x < 10:
print(f'< 10 years old: {x}')
case 10:
print('10 years old.')
case 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18:
print('11~18 years old.')
case 19:
print('19 years old.')
case _:
print('not sure.')
在上面这个示例中,第一个case x if x < 10
表示当age < 10
成立时匹配,且赋值给变量x
,第二个case 10
仅匹配单个值,第三个case 11|12|...|18
能匹配多个值,用|
分隔。
可见,match
语句的case
匹配非常灵活。
匹配列表
match
语句还可以匹配列表,功能非常强大。
我们假设用户输入了一个命令,用args = ['gcc', 'hello.c']
存储,下面的代码演示了如何用match
匹配来解析这个列表:
args = ['gcc', 'hello.c', 'world.c']
# args = ['clean']
# args = ['gcc']
match args:
# 如果仅出现gcc,报错:
case ['gcc']:
print('gcc: missing source file(s).')
# 出现gcc,且至少指定了一个文件:
case ['gcc', file1, *files]:
print('gcc compile: ' + file1 + ', ' + ', '.join(files))
# 仅出现clean:
case ['clean']:
print('clean')
case _:
print('invalid command.')
第一个case ['gcc']
表示列表仅有'gcc'
一个字符串,没有指定文件名,报错;
第二个case ['gcc', file1, *files]
表示列表第一个字符串是'gcc'
,第二个字符串绑定到变量file1
,后面的任意个字符串绑定到*files
(符号*
的作用将在函数的参数中讲解),它实际上表示至少指定一个文件;
第三个case ['clean']
表示列表仅有'clean'
一个字符串;
最后一个case _
表示其他所有情况。
可见,match
语句的匹配规则非常灵活,可以写出非常简洁的代码。