Python 3.10 最大的引入是 Match-Case 语句。 这是 Java switch 语句的 Python 等价物,是许多程序员长期以来一直在寻求的东西。
但是现在这个伟大的命令已经被引入,学习如何充分利用它是很重要的。 这是有关 match-case 语句如何工作的快速指南。
基础
首先,让我们看一个基本的例子。 假设我们有一个将颜色表示为字符串的变量。 它可以是 "green" 、 "red" 、 "yellow" 和 "blue" 。 在 Python 3.9 中,您将使用具有四个分支的 if 语句。
但是,现在我们可以使用 match 语句。 这将使您的代码更易于阅读和维护。 这是执行此操作的代码:
color = "yellow"match color:
case "red":
print("The color is red")
case "yellow":
print("Wow, you picked yellow")
case "green":
print("We are using a green color")
case "blue":
print("Blue like the sea...")
我们首先在 match 关键字之后定义我们要匹配的变量。 然后,每个案例都以 case 关键字开头,然后是我们要检查的模式。 match-case 语句将只运行匹配的第一个 case 下的代码。
因此,在本例中,匹配语句将打印“哇,你选了黄色”。 现在考虑另一种情况:
match color:
case "yellow":
print("Wow, you picked yellow")
case "blue":
print("Blue like the sea...")
case "yellow":
print("Yellow again!")
在这种情况下,永远不会执行匹配“黄色”的第二种情况,因为变量将进入第一种情况,然后跳到语句的末尾(很像 if ... elifcase)。
组合模式
现在假设我们要为黄色和紫色执行相同的代码。 对于两种不同的情况,两次编写相同的代码是不好的做法。
相反,我们可以使用 | 运算符在同一案例中包含多个模式:
match color:
case "yellow" | "purple":
print("Wow, you picked yellow or purple")
case "blue":
print("Blue like the sea...")
case "red":
print("Red here!")
如果颜色是指定的两种颜色之一,则此处将执行第一种情况。
包罗万象的案例
最后,如果变量与任何先前的案例都不匹配,您可能希望有一个将始终执行的案例。 您可以通过以下方式获得:
color = "purple"match color:
case "yellow":
print("Wow, you picked yellow")
case "blue":
print("Blue like the sea...")
case other_color:
print("You chose a different color:", other_color)
在最后一个 case 分支中,other_color 是一个匹配所有内容的变量。 所以在这种情况下,由于没有其他情况与我们的颜色匹配,那么 other_color 将采用与颜色相同的值,我们将执行此代码。
将这个包罗万象的案例放在最后一个很重要:事实上,它总是匹配任何输入,因此它之后的案例永远不会被执行。
匹配列表
现在我们了解了基础知识,让我们看看 Match 语句的一个强大功能:序列上的模式匹配。
我们可以做的最简单的事情是匹配特定元素:
my_list = [1, 2, 3]match my_list:
case [1, 2, 3]:
print("contains 1, 2, 3")
case [4, 5]:
print("Contains 4 and 5")
case _:
print("No match")
这里 my_list 将执行第一种情况下的代码,因为元素是相同的。 请注意,我们还在最后添加了一个包罗万象的案例。
但是,我们可以做的还有很多! 首先,我们可以将一些元素匹配到精确值,而将其他元素留给变量:
my_list = [1, 2, 4]match my_list:
case [1, 2]:
print("contains only 1 and 2")
case [1, 2, el]:
print("Last element is", el)
case _:
print("No match")
看第二种情况:如果列表包含三个元素,这将被执行。 前两个必须是 1 和 2,而最后一个可以是任何值。 变量 el 将获取最后一个元素的值,我们可以在 case 中将其用作普通变量。
此外,我们可以将列表拆分为头部(第一个元素)和尾部(包含除头部之外的所有元素的列表):
match l:
case [head, *tail]:
print("First is", head)
print("Rest is", tail)
case []:
print("Empty")
如果我们想创建一个递归函数,它在头部做某事,然后在列表的其余部分上递归,这特别有用。 例如:
def recursive_sum(my_list):
"""Calculate the sum of the elements with pattern matching"""
match my_list:
case []:
return 0
case [head, *tail]:
return head + recursive_sum(tail)
这里我们递归地计算列表的总和:如果列表为空,总和将为零。 否则,总和是头部的值加上列表其余部分的递归总和。
有条件的情况
现在让我们看看如何使用 if 语句来“停用”某些情况。
例如,假设我们有一个整数 n ,并且我们想要执行模式匹配。 我们有三种情况:一种情况是 nis 为零,一种情况是 n<100,最后一种情况是所有其他情况。 为单个案例编写 99 个值是不切实际的,但幸运的是 Python 具有我们需要的功能:我们可以在案例中添加 if 语句。
下面是我们将如何创建我们的匹配:
num = 5match num:
case 0:
print("It is zero")
case n if n<100:
print(n, "less than 100 but bigger than zero")
case _:
print("A really big number")
如果没有 if 语句,第二种情况将是一个包罗万象的情况,所以第三种情况永远不会被执行。 但是,通过添加 if,仅当 n<100 时才使用第二种情况。 否则,代码将表现得好像这种情况不匹配。
结构模式匹配
最后,我们将看到如何在 match 语句中使用自定义类。
例如,考虑这个类:
class ButtonClicked:
def __init__(self, mouse_button: str, x: int, y: int):
self.x = x
self.y = y
self.mouse_button = mouse_button
该类表示鼠标在屏幕上的点击。 它存储 x 和 y 坐标,以及一个可以是 "left" 或 "right" 的字符串,具体取决于按下鼠标的哪个按钮。
现在我们想要两种不同的情况,一种用于左侧按钮,另一种用于右侧按钮。 这可以通过以下方式实现:
b = ButtonClicked("left", 3, 5)match b:
case ButtonClicked(mouse_button="left"):
print("Left mouse clicked at", b.x, b.y)
case ButtonClicked(mouse_button="right"):
print("Right mouse clicked at", b.x, b.y)
在每种情况下,我们都指定变量 mouse_clicked 应采用哪个值。
结论
感谢您阅读本教程,希望对您有所帮助!