【条件】match
基础语法
match target:
case xxxx:
handler
case xxxx:
handler
case _:
default handler
or 模式
match status:
case 401 | 403 | 404:
print("Not allowed")
case _:
print("Something's wrong with the internet")
通配符匹配任意对象
match-case 的出现有利于提高代码的可读性,让你的代码更加优雅,但同时要使用好它,也是有一些门槛的,特别是通配符的使用。
import sys
match sys.argv[1:]:
case ["quit"]:
print("exit")
case ["create", user]: # 创建单个用户
print("create", user)
case ["create", *users]: # 批量创建多个用户
for user in users:
print("create", user)
case _:
print("Sorry, I couldn't understand the argv")
最后一个 case 中的 _
并不作为变量名,而表示一种特殊的模式,在前面的 case 中都未命中的情况下,该 case 会是最后的保障,能确保命中,它相当于 Go 语言中的 default
分支。
使用可变参数 *args
第二个 case 和 第三个 case 非常的像,区别在于第三个 case中 users
前加了个 *
,他跟原 Python 函数中的可变参数是一个用法,会匹配列表的多个值。
在该中表示可以从命令行参数中批量创建用户。
import sys
match sys.argv[1:]:
case ["create", *users]: # 批量创建多个用户
for user in users:
create(user)
case _:
print("Sorry, I couldn't understand the argv")
$ python3 xxx.py create user1 user2 user3
长度的匹配方式
若你希望使用 case 仅对对象的长度做一些匹配,可以使用下面这样的方式
[*_]
匹配任意长度的list
;(_, _, *_)
匹配长度至少为 2 的tuple
。
类对象的匹配
通过创建一个临时对象模板,跟目标进行匹配
class Coords:
def __init__(self, x, y):
self.x, self.y = x, y
def match_location(coords):
match coords:
case Coords(x=0, y=0):
print('当前坐标为原点处')
case Coords(x=0, y=y):
print('当前坐标在y轴上')
case Coords(x=x, y=0):
print('当前坐标在x轴上')
case Coords():
print('当前不在轴上')
case _:
print('这不是一个有效的坐标')
注意点
匹配要注意顺序
match-case 这样一个看似简单的新功能,却有着不少的学习成本,如果对 结构模式匹配 半知半解的人来说,可能会增大代码出错的概率,因为 match-case 在面对不同的对象,它的匹配的规则也有所不同。
- 当 match 的对象是一个 list 或者 tuple 的时候,需要长度和元素值都能匹配,才能命中,这就是为什么下面这个例子走的是第三个 case 而不是第二个 case。
- 当 match 的对象是一个 dict 的时候,规则却有所不同,只要 case 表达式中的 key 在所 match 的对象中有存在,即可命中。
- 而当 match 的对象是类对象时,匹配的规则是,跟 dict 有点类似,只要对象类型和对象的属性有满足 case 的条件,就能命中。