Python重大变化:match-case模式匹配

花下猫语:有很多人期待在 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

(0)

相关推荐

  • Python 超级强大的模式匹配工具—Pampy

    作者丨Ckend 来源丨Python实用宝典(ID:pythondict) 在自然语言处理界,模式匹配可以说是最常用的技术.甚至可以说,将NLP技术作为真实生产力的项目都少不了模式匹配. 什么是模式匹 ...

  • Python 中的神秘运算符

    今天我们来讲讲 Python 里一个不为众人所知的运算符.你可能会觉得疑惑:还有我不知道的运算符?别急着下结论,先往下看看再说. 在 Python3.5 中通过 PEP465 (https://www ...

  • Python 3.10来了,switch语法终于出现

    机器之心报道 编辑:陈萍 不用再自己琢磨如何实现 switch 功能了. 对于从事数据科学和人工智能领域的人们来说,Python 是大家的首选编程语言.根据最近的一项调查,27% 的程序员开发职位要求 ...

  • Python的match和search区别是什么?

    在学习Python的过程中,很多人傻傻分不清match和search区别,那么你知道Python开发中match和search的区别是什么吗?如果不知道,这篇文章一定要看,会给你带来一定的帮助. 什么 ...

  • python笔记56-re正则匹配re.match

    前言 re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none. re.search 扫描整个字符串并返回第一个成功的匹配. re.match ...

  • Python 强大的模式匹配工具

    简说Python 1周前 以下文章来源于Python实用宝典 ,作者Ckend  简说Python推荐  来源|Python实用宝典 作者|Ckend 在自然语言处理界,模式匹配可以说是最常用的技术. ...

  • Python正则表达式之re.match()分组

    https://www.jianshu.com/p/cc26837242b1 我们在面对生物数据,比如序列信息(比如碱基序列.氨基酸序列等)的时候, 会时常要问,这其中是否包含着且含有多少某种已知的模 ...

  • 说说Python中search()和match()的区别?

    公众号新增加了一个栏目,就是每天给大家解答一道Python常见的面试题,反正每天不贪多,一天一题,正好合适,只希望这个面试栏目,给那些正在准备面试的同学,提供一点点帮助! 小猿会从最基础的面试题开始, ...

  • 重大变化!心理治疗、中医经络检测……广东将可用医保支付

    好消息! 广东有了 全省统一的 医保药品.诊疗项目.医用耗材目录啦! 自2021年8月15日起实施全省统一的.准入法管理的诊疗项目.医用耗材目录,这也是广东自建立基本医疗保险制度以来的第一次. &qu ...

  • Python|二叉树叶子结点问题解决方法

    问题描述键盘输入一颗二叉树,求解其叶子结点个数.示例: 输入:4,2,6,1,3,5输出:3解决方案一棵树当中没有子结点(即度为0)的结点称为叶子结点,简称"叶子".当二叉树为空时 ...

  • Python数据分析库有哪些?常见分类!

    众所周知,Python前景好.需求量大.薪资高.就业岗位多,除了基本的开发工作之外,还可以从事人工智能.数据分析.网络爬虫等岗位.那么说起数据分析,你知道Python常用数据分析库有哪些吗?我们一起来 ...