Python 的新特性-模式匹配

2021-03-16 12:00:16 浏览数 (1)

经过两三年,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状态码都是需要返回同一个错误码的话,还可以写的更简单:

代码语言:javascript复制
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。

0 人点赞