简述
截至Python 3.10.0 (alpha6 发布于2021年3月30日),Python有了一种官方的语法等效形式,称为match
。
基本语法如下:
match value:
case condition:
action(s)
...
对于较旧版本的Python,如果您不想使用if
-elif
-else
语句,只有一些变通方法可供选择。请参阅这篇出色的社区帖子以获取其中的一些方法。
示例
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 _:
print("The number is none of 10, 2*10 or 100")
因此,其他涉及解决方法的答案从性能角度来看也不再有效。
重要通知
如果你已经了解了支持 switch 和 case 的语言的行为,那么对于 Python,有一些需要注意的差异。
Cases don't fall through
It's common that languages with switch
-case
statements execute every case the value matches - from top to bottom. Hence, there is a third statement - break
- to be used in switch
-case
constructs if you don't want to fall through:
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.");
}
In this example, the first two cases would be executed because the first case falls through. If there was no break
statement inside the second case, all cases, including the default one, would be executed.
In Python, only the first matching case is being executed. You can think of it like every case would contain a hidden break
statement.
Variable references don't work as a condition
base_color = "red"
chosen_color = "green"
match chosen_color:
case base_color:
print("Yes, it matches!")
This code does actually print that the colors match!
Bare variable references as case conditions will always match.
Regardless, literals like case "red": ...
and qualified (i.e. dotted) names like case AllColors.red
work like expected - no need to be scared of them.
All of this is the case, because the Python Software Foundation did not decide to just copy another boring control flow model, but to actually implement a fully-fledged pattern matcher which is more than just a switch
-case
statement. More on this can be found in the next section.
强大的模式匹配
match
- 匹配啊,不能太过于简单粗暴
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
现在是一个占位符,它被赋予了我们选择的颜色的值。
这种高级模式匹配有更多的用例,在Python文档中提到了一些有趣的例子。
结语
Python 3.10 得到应有的采用还需要时间。Python 3.10.0 预计于2021年10月4日发布稳定版 - 这意味着它可能会包含在 Ubuntu 22.04 及以上版本中。
如果你只想玩一下并编写自己的程序,将其部署到自己的服务器上,或者如果你打算以打包形式而不是裸源代码文件分发你的创作,请在你的程序中尝试这个新功能 - 它会带来好处!
补充
尝试 Python 3.10.0
对于 Windows 和 macOS 用户,此页面提供了官方安装程序下载。
在 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
替换为不同的版本。