Python 从 3.10 版本开始增加了 match 语句,和其他语言常见的 switch 语句极其相似,但功能更加强大。
本文通过实例,了解下其用法。
基本的 match 语句
def http_code(status):` `match status:` `case 400 | 404 | 418:` `return "40x request"` `case 200 | 216:` `return "20x request"` `case 500 | 503:` `return "50x request"` `case _:` `return "other codes"`` ``print(http_error(404)) # 40x request
-
不同的选项可以用“或”运算写在一起。
-
匹配了一个 case 后就不会匹配其他 case 了。
-
不同数据类型可以混合使用。
-
_ 匹配剩余的任意情况。
带 if 语句的 case
def check_num(num, guard):` `match num:` `case 1 | 2 | 3 if guard == True:` `print("in case 135")` `case _:` `print("there is something wrong")`` ``check_num(2, False)``check_num(2, True)``check_num(5, True)
如果 if 条件语句不通过,会继续匹配后边的 case。
带as语句的case
go_to = "east"``match go_to:` `case "north" | "south" | "east" | "west" as direction:` `print("go", direction) # go east
使用as语句,在同时多个匹配条件时,可以知道匹配的具体是谁。
匹配枚举类型
from enum import Enum`` `` ``class Color(Enum):` `RED = 'red'` `GREEN = 'green'` `BLUE = 'blue'`` `` ``color = Color('green')`` ``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 :(")``
匹配序列
point = (0, 8)`` ``match point:` `case (0, 0):` `print("Origin")` `case (0, y):` `print(f"Y={y}") # Y=8` `case (x, 0):` `print(f"X={x}")` `case (x, y):` `print(f"X={x}, Y={y}")` `case _:` `raise ValueError("Not a point")
可以匹配元组 (tuple) 或列表 (list),按顺序逐位匹配,如果对应位置是个变量,就把传入的内容对应位置的值提取出来。
这种情况也可以用if条件句,且被提取出来的变量可以用到条件中。
序列的通配符提取
point = (0, 1, 8, 8, 8, 8)``match point:` `case (0, 0):` `print("0, 0")` `case (0, 1, *numbers):` `print(0, 1, numbers) # 0 1 [8, 8, 8, 8]`` ` `case _:` `print("Error")
匹配了前两位是 0,1,后边的会提取到 numbers 列表变量。
匹配字典
point = {"x":2, "y":4 , "z":9}`` ``match point:` `case {"x":2,"y":y}:` `print(f"Y={y}") # Y=4` `case _:` `print("Something else")
和列表一样,按 key 名称,部分匹配,部分提取。同时可以看到被匹配的变量可以多出内容,match 只关心它需要的。
字典的通配符提取
my_nu = {"x": 1, "y": 2, "z": 3, "o": 4}``match my_nu:` `case {"x": 1, "y": 1}:` `print("x:1, y:1")` `case {"x": 1, "y": 2, **nums}:` `print("x:1, y:2", nums)
nums变量是个字典,匹配了x,y后,其他所有键值对都会放入nums中。
同时可以指定匹配的数据类型:
actions = [` `{"text": "Any class is a valid match target", "color": "green"},` `{"text": "Any class is a valid match target", "color": 7},`` ``]``for action in actions:` `match action:` `case {"text": str(message), "color": str() as c}:` `print("message:", message, "color:", c)` `case _:` `print("Unsupported action")
有两种格式可以选择:str(message) 和 str() as c
匹配类
class Point:` `__match_args__ = ('x', 'y')` `def __init__(self, x, y):` `self.x = x` `self.y = y`` ``def where_is(point):` `match point:` `case Point(0, 0): # Point(x=0, y=0):` `print("Origin")` `case Point(0, y): # Point(x=0, y=y):` `print(f"Y={y}")` `case Point(x, 0): # Point(x=x, y=0):` `print(f"X={x}")` `case Point():` `print("Somewhere else")` `case _:` `print("Not a point")`` ``point = Point(0,9)``where_is(point)
类的匹配也很有意思,如果类内定义了 __match_args__ 成员变量,就可以按其定义的属性顺序按位置参数的形式匹配;如果没有定义这个变量,也可以用关键字参数直接匹配(注释中的形式)。同时也可以做到部分用于匹配,部分用于提取值。
这种匹配我理解的匹配方式是,用 case 后边的关键字名称(直接获得或者从 __match_args__ 中获得)从传入的 point 实例中取得对应的属性进行匹配。
把类嵌入序列进行匹配
class Point:` `__match_args__ = ('x', 'y')`` ` `def __init__(self, x, y):` `self.x = x` `self.y = y`` `` ``points = [Point(0, 9), Point(0, 5)]`` ``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")
参考:
https://docs.python.org/3/tutorial/controlflow.html#match-statements
https://peps.python.org/pep-0636/
题外话
感兴趣的小伙伴,赠送全套Python学习资料,包含面试题、简历资料等具体看下方。
👉CSDN大礼包🎁:全网最全《Python学习资料》免费赠送🆓!(安全链接,放心点击)
一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具
工具都帮大家整理好了,安装就可直接上手!
三、最新Python学习笔记
当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
四、Python视频合集
观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
五、实战案例
纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
六、面试宝典
简历模板
👉CSDN大礼包🎁:全网最全《Python学习资料》免费赠送🆓!(安全链接,放心点击)
若有侵权,请联系删除