match语句(python3.10)
在很多语言中,有一种用于条件判断的switch-case语句,但是在python中一直以来,没有switch-case。不过在python3.10的新版本中,加入了match-case语句。
match语句的基础使用方法与switch-case语句比较类似,是通过match和case之间的组合,完成结构化模式匹配。但是match语句不等同于switch-case,因为match语句还有一些其他的功能可用。
另外值得注意的是,虽然截止到目前版本(2021年11月),match和case还没有被正式添加到关键字列表中,也就说目前你仍然可以将match和case作为变量,函数名等使用,但是预计在不久以后,match和case可能就将添加进关键字列表中。
基础用法:匹配字面值
如果你曾经学习或使用过switch语句,那么你应该对match的基础用法并不感觉到陌生。不过值得注意的是,在python中,一直以来是有缩进要求的,在case处需要缩进一次,在case里面,还需要缩进一次。另外与switch-case不同的是,python中无需使用break跳出语句,一旦有match匹配成功,就会结束语句。除此之外,还添加了_通配符,作为如果前边都没匹配成功的话,去执行的case来使用。
a = 520
match a:
case 314:
print("314")
case 520:
print("520")
case 1314:
print("1314")
case _:
print("什么也没有")
以上代码的运行结果是,打印520。由于变量a在case 520处匹配成功,因此,执行该段代码中的内容,并结束。虽然没有使用break,但是不会和swtich-case一样,继续往下执行。
如果,你要同时匹配多个字面值,可以通过|连接,它起到的作用相当于"or",但是不能用or来代替|。
case 520 | 1314:
print("5201314")
如果多个case选项都能被匹配成功,那么仍然也只会执行第一个匹配成功的case代码段,后续能匹配成功的case也不会被运行。
另外在python中,case匹配的内容没有限制,浮点数,列表等等也可以放进去匹配。不过需要注意的是,列表必须要元素顺序一致,才能匹配成功,但是在字典中没有这样的要求,无论键值添加的时候是什么顺序,都不影响匹配结果。
特殊用法:绑定变量
如果在match语句的case中,出现了变量(或者说是标识符),那么,这个变量就会尽可能去匹配match的内容,并被赋值。
a = 520
match a:
case b:
print("520")
print(b) # 此时b的结果为520,无论b之前是否曾被定义过
以上代码使用了一个根本不存在的变量名b去匹配a,结果是被匹配成功,并且b被赋值为了a的值。
当然,如果只是这样的话,那么并不能直接看出有什么使用的意义,因此,它的价值在于,可以类似于拆包,去匹配一个列表或者元组。
a = [520, 1314]
match a:
case [1314, b]:
print(1)
case [520, c]:
print(2)
# 这段代码运行结束后,会打印2
# 因为[1314, b]不能和[520, 1314]匹配成功
# 因此[520, c]匹配成功,c被赋值为1314
说到列表和元组,我们还需要提到的一件事情是,在当前的match语句的匹配中,并不区分列表和元组,他们在匹配中是一样的。
a = [520, 1314]
match a:
case (520, 1314):
print("可以被匹配成功")
a = (520, 1314)
match a:
case [520, 1314]:
print("这也可以被匹配成功")
通配符
之前,我们已经介绍过了,match语句使用了单个下划线_作为通配符,单独使用的功能类似于switch-case语句中的default,但是实际上,通配符不仅可以在语句最后单独使用,也可以作为组合使用的通配符,参与到解包之中。
a = [520, 1314]
_ = 12
match a:
case [1314, _]:
print(1)
case [520, _]:
print(2)
case _:
print(3)
# 以上代码的执行结果是,打印2,因为[520, _]被匹配成功了
# 值得注意的是,此时变量_的打印结果仍然为12
# 因为参数匹配的_是通配符_,并非是之前特殊模式中提到的变量参与匹配
# 因此,最终匹配成功的结果,不会赋值给同名的变量_
print(_)
守护项(if条件判断)
在case之中,我们可以加入一个if条件判断来作为守护项。如果if条件判断不成功的话,那么该case语句不会被采用,继续去寻找下一个case。使用方法类似于在列表推导式中,添加一个if。
a = [520, 1314]
match a:
case [x, y] if x > y:
print("x > y")
case [x, y] if x < y:
print("x < y")
# 以上代码的运行结果为,x < y
注意:case的匹配和case中if判断的触发时机为,先进行匹配,然后再开始if判断。所以,虽然变量x和y都没有出现过,但是不要紧,因为当x,y匹配成功以后,才会去进行if判断,此时的x和y已经被赋值了,可以进行比较,不会出现变量未定义的情况。
这种匹配和if判断的先后顺序意味着,即使if判断未成功,只要匹配能成功,变量依然会被赋值。
a = [520, 1314]
match a:
case [x, y] if x > y:
print("此段代码不会被打印")
print(x, y) # 此时x为520,y为1314
# 虽然if判断没有成功,case中的内容也没有被执行
# 但是由于case的匹配先于if判断成功了,因此变量x和y均完成了赋值
总结
1,match语句的基础功能和switch-case类似,都能完成条件判断,但是match语句的功能更强,在匹配中并不限制变量类型。
2,match语句执行完成第一个成功匹配的case段以后就会结束,不会继续去寻找下一个case,也无需手动使用break。
3,match语句中没有使用default,而是选择了通配符_,可以通过case 放置在最后表示任何时候都能匹配成功,也可以把通配符用于解包之中。
4,match语句可以完成类似于解包的功能,只要在case中使用变量即可,会尽可能完成匹配,并对变量进行赋值。
5,match语句中可以添加if判断作为守护项,但是要注意的是,case匹配的触发时间要早于if判断。因此只要匹配能够成功,即使if判断失败,变量仍然会被赋值。
最后,我是瞎老弟,专注于python学习,喜欢的话,请关注我,你们的支持对于我来说,真的非常重要!