查看原文
其他

Python 重大变化:是 match-case,不是 switch-case

The following article is from 不羁的学习 Author 不羁的凉皮儿

有很多人期待在 Python 中使用 switch-case 语句,Python 社区里针对它有过长达数年的讨论(PEP-275、PEP-3103),然而结论是不支持。最近,官方终于通过了PEP,Python 将要迎来一次重大更新!match-case 与 switch-case 的结构相似,然而其思想与用途有着巨大差别。有人喜欢,有人憎恶。今天分享一篇文章,让大家见识一下这个新东西到底有什么本事。

前言

2021 年 2 月 8 日,指导委员会通过了 PEP 634, PEP635, PEP636,至此,Python 总算拥有了 match-case, 不用再写一连串的 if-else 了

嘿喂狗

1

最简单的形式如下,将 match 主题表达式与一个或多个字面量模式进行比较

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"  
  

最后一个 case 中,case _:类似于 C 和 Java 中的default:,永远不会匹配失败,即当其他 case 都无法匹配时,匹配这条

2

可以使用|将多个字面量组合起来表示或

...  
        case 401|403|404:  
            return "Not allowed"  

3

模式也可以是解包操作,用于绑定变量

# 主题表达式是一个(x, y)元组  
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")  

注意,第一个模式中有两个字面量,可以看作是上述普通模式的加强版。但是后两个模式有些不同,元组中一个是字面量一个是变量,这个变量会捕获主题元组中的值。同理,第四个模式case (x, y):会捕获两个值,这在理论上与解包作业相似,就如同point(x, y) = point

4

如果使用了结构数据类,比如data classes,可以用类似于构造函数'类名+参数列表'的形式,但是用来捕获变量

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")  

5

也可以使用关键字参数。下列关于y, var的模式都是等价的,并且都将属性绑定到了变量上

Point(1, var)  
Point(1, y=var)  
Point(x=1, y=var)  
Point(y=var, x=1)  

6

模式可以被简单粗暴的嵌套起来,例如我们有一组 points 的列表,就可以像这样匹配

match points:  
    case []:  
        print("No points")  
    case [Point(0, 0)]:  
        print("The origin")  
    case [Point(x, y)]:  
        print(f"Single point {x}, {y}")  
    case [Point(0, y1), Point(0, y2)]:  
        print(f"Two on the Y axis at {y1}, {y2}")  
    case _:  
        print("Something else")  

7

给模式添加 if 从句以充当门卫。如果为假,就移步到下一个 case。注意,模式捕获值发生在从句执行前

match point:  
    case Point(x, y) if x == y:  
        print(f"Y=X at {x}")  
    case Point(x, y):  
        print(f"Not on the diagonal")  

8

子模式可以使用as捕获

case (Point(x1, y1), Point(x2, y2) as p2): ...  

9

模式可以使用命名的常量,且必须使用.以防止被解释为捕获变量

from enum import Enum  
class Color(Enum):  
    RED = 0  
    GREEN = 1  
    BLUE = 2  
  
match color:  
    case Color.RED:  
        print("I see red!")  
    case Color.GREEN:  
        print("Grass is green")  
    case Color.BLUE:  
        print("I'm feeling the blues :(")  

10

字面量会被特殊对待,例如None, False, True,是使用is完成匹配的例如:

match b:  
    case True:  
        print("Yes!")  

就完全等价于这样

    if b is True:
        print("Yes!")

多谢

关于 match-case 的用法可能已过时或理解不准确,如有错漏地方欢迎指正,共同学习,权威及最新信息可关注Guido 老爷子的官方 repo[1]

参考资料

参考资料

[1]

Guido老爷子的官方repo: : https://github.com/gvanrossum/patma



- EOF -

推荐阅读  点击标题可跳转

1、Python 有可能删除 GIL 吗?

2、Python 绘制地图神器,上手直接开大!

3、0 代码就能做 Python 数据分析,这个 Jupyter 插件,用起来就像 Excel 一样简单


觉得本文对你有帮助?请分享给更多人

推荐关注「Python开发者」,提升Python技能

点赞和在看就是最大的支持❤️

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存