问题描述
C/C++、C#、Java、JavaScript 和 Pascal 等编程语言 (Reference) 组合了 switch
和 case
语句(有时也称为 select
或inspect
) 允许您根据多个条件检查一个值以执行某些操作.
Programming languages like C/C++, C#, Java, JavaScript and Pascal (Reference) have a combination of switch
and case
statements (sometimes also called select
or inspect
) which allow you to check one value against several conditions to perform certain actions.
my_value = 10;
switch(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");
default:
print("The number is none of 10, 2*10 or 100");
}
描述 switch
-case
构造的特殊语法的伪代码.
Pseudo-Code to depict the special syntax of the switch
-case
construct.
了解像 dictionary-lookups 这样的功能等价物,是否有一个纯粹的 句法 等价物到上面的编程结构?
Being aware of functional equivalents like dictionary-lookups, is there a purely syntactical equivalent to the above programming construct?
推荐答案
TL;DR
截至 Python 3.10.0 (alpha6 2021 年 3 月 30 日发布),Python 有一个官方的语法等价物,称为 匹配
.
基本语法是:
match value:
case condition:
action(s)
...
对于较旧的 Python 版本,只有当您不想使用 if
-elif
-else
时,才有解决方法.请参阅这篇出色的社区帖子,了解其中的一些内容.
For older Python versions, there are only workarounds if you don't want to resort to if
-elif
-else
.
See this excellent community post for a collection of some.
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")
因此,涉及变通办法的其他答案不再有效 - 从性能的角度来看也是如此.
Therefore, other answers involving workarounds aren't valid anymore - also from a performance point of view.
如果来自支持 switch
和 case
的语言,您可能已经知道它们的行为.不过,对于 Python,有一些差异需要注意.
If coming from languages which support switch
and case
, it's likely that you already know about their behavior. With Python, there are some differences to note though.
案件不会落空
具有 switch
-case
语句的语言通常会执行值匹配的 每个 case - 从上到下.因此,如果您不想失败,可以在 switch
-case
构造中使用第三条语句 - break
:
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.");
}
在此示例中,将执行前 两个 案例,因为第一个案例失败了.如果第二种情况下没有 break
语句,则所有情况,包括默认情况,都会被执行.
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.
在 Python 中,只执行第一个匹配的案例.你可以把它想象成每个 case 都包含一个隐藏的 break
语句.
In Python, only the first matching case is being executed. You can think of it like every case would contain a hidden break
statement.
变量引用不能作为条件使用
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!
裸变量引用,因为大小写条件始终匹配.
无论如何,像 case "red": ...
和 qualified (即虚线)名称(如 case AllColors.red
)都可以工作正如预期的那样 - 无需害怕它们.
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.
所有这一切都是如此,因为 Python 软件基金会并没有决定只是复制另一个无聊的控制流模型,而是真正实现了一个成熟的模式匹配器,它不仅仅是一个switch
-case
语句.更多信息请参见下一节.
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
- M匹配ain't case h哎呀
match
- Match ain't case hooey
Python 增强提案 (PEP) 编号中提供的规范和信息.634-636
在 Python 中,match
实际上不仅仅是一个简单的开关——因此可能是这个名字.它具有特殊功能,例如深层占位符和通配符.
In Python, match
is actually much more than a simple switch - therefore probably the name. It features special functionality like deep placeholders and wildcards.
受阅读文档启发的示例 - 所以您不必:
match point:
case (0, 0):
print("Origin")
case (0, y):
print("Our current Y position is", y, " now.")
您可以匹配任意嵌套的数据结构,包括占位符.在上面的例子中,我们匹配一个包含两个项目的元组,在第二种情况下,我们使用一个占位符 y
,它在匹配时获得它的值.
You can match arbitrary nested data structures, including placeholders. In the above example, we are matching a tuple with two items where in the second case, we use a placeholder y
that gets its value assigned upon matching.
您也可以匹配类属性,以非常相似的方式:
You can also match class attributes, in a very similar fashion:
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
:
This also explains why you can't match single variable references in case conditions: you don't actually match against the value of that variable but actually introduce a placeholder of that same name!
Therefore, if you were going to print chosen_color
like this:
base_color = "red"
chosen_color = "green"
match chosen_color:
case base_color:
print("Our base color is", base_color)
它实际上会打印出来
我们的底色是绿色
因为 base_color
现在是一个占位符,它被分配了我们 chosen_color
的值.
because the base_color
is now a placeholder which gets assigned the value of our chosen_color
.
这种高级模式匹配还有很多用例,其中一对有趣的例子在 Python 文档.
There are a lot more use cases for this advanced pattern matching, an interesting couple of them mentioned in the Python documentation.
Python 3.10 得到应有的采用还需要一段时间.Python 3.10.0 将于 2021 年 10 月 4 日稳定发布 - 这意味着它可能包含在 Ubuntu 22.04 及更高版本中.
It will take its time until Python 3.10 gets its deserved adoption. Python 3.10.0 is set to be released stable on October 4, 2021 - meaning it might be included in Ubuntu 22.04 and up.
如果您只是想自己动手编写程序,请将它们部署到您自己的服务器上,或者如果您打算以打包形式而不是作为纯源代码文件分发您的作品,请尝试一下这个新功能你的程序 - 这将是一个好处!
If you just want to play around and write programs for yourself, deploy them to your own server, or if you intend to distribute your creations in packaged form and not as plain source code files, give this new feature already a try in your programs - it's going to be a benefit!
对于 Windows 和 macOS 用户,此页面 具有官方安装程序下载功能.
For Windows and macOS users, this page features the official installer downloads.
在 Debian 和 Ubuntu 上,您可以使用非常流行的DeadSnakes"-project PPA:
On Debian and Ubuntu, you can use the very popular "DeadSnakes"-project 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 的一个选项,无需任何复杂的设置步骤,并且在完全隔离的环境.
Trying Python 3.10.0 without destroying your system
Docker is an option for using Python 3.10 without any complicated setup steps and in a completely isolated environment.
docker run -it python:3.10.0a6-alpine
就是这样.随着时间的推移,可能会发布新的 alpha 或 beta 版本.您需要将 a6
替换为 不同版本 那么.
And that's it. As the time passes by, new alpha or beta versions might be released. You will want to replace the a6
with a different version then.
这篇关于Python 中 switch/case 的语法等价物是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!