TL;DR
从 Python 3.10.0 (alpha6 released 2021 年 3 月 30 日)开始,Python 有一个官方的等效语法,称为 match。
基本语法是:
match value:
case condition:
action(s)
...
对于较旧的 Python 版本,如果您不想求助于 if-elif-else,则只有解决方法。
请参阅这个出色的 community post 以获取一些集合。
示例
my_value = 10
match my_value:
case 10:
print("The number is ten")
case 2*10:
print("The number is the double of ten")
case 100:
print("The number is one hundred")
case _:
# this is the default handler if none
# of the above cases match.
print("The number is none of 10, 2*10 or 100")
因此,涉及变通办法的其他答案不再有效 - 从性能的角度来看也是如此。
重要提示
如果来自支持switch 和case 的语言,您可能已经知道它们的行为。不过,对于 Python,有一些差异需要注意。
-
案件不会落空
具有switch-case 语句的语言通常会执行每个值匹配的情况 - 从上到下。因此,如果您不想失败,可以在 switch-case 构造中使用第三条语句 - break:
value = 10
switch (value) {
case 10:
print("Value is ten");
case 2*5:
print("Value is the double of five");
break;
case 20/2:
print("Value is the half of twenty");
default:
print("This is just the default action.");
}
在此示例中,将执行前 两个 案例,因为第一个案例失败了。如果在第二种情况下没有break 语句,则将执行所有情况,包括默认情况。
在 Python 中,只执行第一个匹配的案例。你可以把它想象成每个案例都包含一个隐藏的break 语句。
-
变量引用不能作为条件使用
base_color = "red"
chosen_color = "green"
match chosen_color:
case base_color:
print("Yes, it matches!")
这段代码确实打印出颜色匹配!
裸变量引用,因为大小写条件始终匹配。
无论如何,像 case "red": ... 这样的文字和像 case AllColors.red 这样的限定(即虚线)名称的工作方式与预期一样 - 无需害怕它们。
所有这一切都是如此,因为 Python 软件基金会并没有决定只是复制另一个无聊的控制流模型,而是实际实现一个成熟的模式匹配器,它不仅仅是一个switch-case 声明。更多信息请参见下一节。
强大的模式匹配
match - Match ain't case h哎哟
Python Enhancement Proposals (PEP) nos. 634-636中提供的规格和信息
在 Python 中,match 实际上不仅仅是一个简单的开关——因此可能是这个名字。它具有特殊功能,例如深层占位符和通配符。
受阅读文档启发的示例 - 所以您不必:
match point:
case (0, 0):
print("Origin")
case (0, y):
print("Our current Y position is", y, " now.")
您可以匹配任意嵌套的数据结构,包括占位符。在上面的示例中,我们正在匹配一个包含两个项目的元组,在第二种情况下,我们使用占位符 y 来获取匹配时分配的值。
您也可以匹配类属性,以非常相似的方式:
class Point:
x: int
y: int
def location(point):
match point:
case Point(x=0, y=0):
print("Origin is the point's location.")
case Point(x=0, y=y):
print("The point lies on the y axis at a height of", y, "units.")
这也解释了为什么您不能在 case 条件下匹配单个变量引用:您实际上并没有匹配该变量的值,而是实际上引入了同名的占位符!
因此,如果您要像这样打印chosen_color:
base_color = "red"
chosen_color = "green"
match chosen_color:
case base_color:
print("Our base color is", base_color)
它实际上会打印出来
我们的底色是绿色
因为base_color 现在是一个占位符,它被分配了chosen_color 的值。
这种高级模式匹配还有很多用例,Python documentation 中提到了其中的一对。
结语
Python 3.10 得到应有的采用还需要一段时间。 Python 3.10.0 将于 2021 年 10 月 4 日稳定发布 - 这意味着它可能包含在 Ubuntu 22.04 及更高版本中。
如果您只是想自己动手编写程序,请将它们部署到您自己的服务器上,或者如果您打算以打包的形式而不是作为纯源代码文件分发您的作品,请尝试一下这个新功能你的程序 - 这将是一个好处!
附录
尝试 Python 3.10.0
对于 Windows 和 macOS 用户,this page 提供官方安装程序下载。
在 Debian 和 Ubuntu 上,您可以使用非常流行的“DeadSnakes”项目 PPA:
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.10
python3.10 --version
在不破坏系统的情况下尝试 Python 3.10.0
Docker 是在完全隔离的环境中使用 Python 3.10 的一个选项,无需任何复杂的设置步骤。
docker run -it python:3.10.0a6-alpine
就是这样。随着时间的推移,可能会发布新的 alpha 或 beta 版本。然后,您需要将 a6 替换为 different version。