经过两三年,Python 终于出了一个值得写一写的特性。从 Python3.6 开始,Python 的语法层面的改动一直都没有发生大的改变,直到最近的 PEP622,也就是模式匹配。对于模式匹配的这个语法而言,第一次接触是在学习Scala的过程中,这是一个非常好用的特性,可以极大的改变 if/else 的写法,让代码写的更加优美。举个例子,比如我们要匹配Http状态的话,没有模式匹配的,使用if/else的话,会写成下面这样:
代码语言:javascript复制def http_error(status):
if status == 400:
return "Bad request"
else if status == 401:
return "Unauthorized"
else if status == 403:
return "Forbidden"
else if status == 404:
return "Not found"
else if status == 418:
return "I'm a teapot"
else:
return "Something else"
使用模式匹配的话,代码就会简化很多:
代码语言:javascript复制def http_error(status):
match status:
case 400:
return "Bad request"
case 401:
return "Unauthorized"
case 403:
return "Forbidden"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case _:
return "Something else"
其中_
符号表示:如果前面的模式都没匹配上的话,就会执行_
对应的语句。并且如果多个Http状态码都是需要返回同一个错误码的话,还可以写的更简单:
case 401|403|404:
return "Not allowed"
模式匹配还能做到更多,比如类似于Scala的拆包:
代码语言:javascript复制# The subject is an (x, y) tuple
match point:
case (0, 0):
print("Origin")
case (0, y):
print(f"Y={y}")
case (x, 0):
print(f"X={x}")
case (x, y):
print(f"X={x}, Y={y}")
case _:
raise ValueError("Not a point")
甚至还可以使用类
代码语言:javascript复制from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
def whereis(point):
match point:
case Point(0, 0):
print("Origin")
case Point(0, y):
print(f"Y={y}")
case Point(x, 0):
print(f"X={x}")
case Point():
print("Somewhere else")
case _:
print("Not a point")
具体的可以参考https://github.com/gvanrossum/patma/blob/master/README.md#tutorial 这个教程。作者就是 Python 的创始人 Guido van Rossum。