【发布时间】:2011-07-23 09:30:57
【问题描述】:
最近,我在网上看到一些关于 Python 中没有好的“switch/case”等价物的讨论。我意识到有几种方法可以做类似的事情——一些使用 lambda,一些使用字典。还有其他关于替代方案的 StackOverflow 讨论。甚至有两个 PEP(PEP 0275 和 PEP 3103)讨论(并拒绝)将 switch/case 集成到语言中。
我想出了一种我认为很优雅的 switch / case 方式。
它最终看起来像这样:
from switch_case import switch, case # note the import style
x = 42
switch(x) # note the switch statement
if case(1): # note the case statement
print(1)
if case(2):
print(2)
if case(): # note the case with no args
print("Some number besides 1 or 2")
所以,我的问题是:这是一个有价值的创作吗?你有什么改进的建议吗?
我放了include file on github,以及大量示例。 (我认为整个包含文件大约有 50 行可执行文件,但我有 1500 行示例和文档。)我是否过度设计了这个东西,浪费了很多时间,还是有人会觉得这值得?
编辑:
试图解释为什么这与其他方法不同:
1)多条路径是可能的(执行两个或多个案例),
这在字典方法中更难。
2)可以检查“等于”以外的比较
(例如 case(less_than(1000))。
3) 比字典方法更具可读性,可能还有 if/elif 方法
4) 可以跟踪有多少真实案例。
5) 可以限制允许的 True 案例的数量。 (即执行
前 2 个真实案例...)
6) 允许默认情况。
这里有一个更详细的例子:
from switch_case import switch, case, between
x=12
switch(x, limit=1) # only execute the FIRST True case
if case(between(10,100)): # note the "between" case Function
print ("%d has two digits."%x)
if case(*range(0,100,2)): # note that this is an if, not an elif!
print ("%d is even."%x) # doesn't get executed for 2 digit numbers,
# because limit is 1; previous case was True.
if case():
print ("Nothing interesting to say about %d"%x)
# Running this program produces this output:
12 has two digits.
这是一个示例,试图展示 switch_case 如何比传统的 if/else 更清晰和简洁:
# conventional if/elif/else:
if (status_code == 2 or status_code == 4 or (11 <= status_code < 20)
or status_code==32):
[block of code]
elif status_code == 25 or status_code == 45:
[block of code]
if status_code <= 100:
[block can get executed in addition to above blocks]
# switch_case alternative (assumes import already)
switch(status_code)
if case (2, 4, between(11,20), 32): # significantly shorter!
[block of code]
elif case(25, 45):
[block of code]
if case(le(100)):
[block can get executed in addition to above blocks]
大大节省了冗长的 if 语句,其中反复重复相同的 switch。不确定用例的频率有多高,但似乎在某些情况下这是有意义的。
github 上的示例文件还有更多示例。
【问题讨论】:
-
这应该作为另一个 PEP 提交。
-
这与传统的
if有何不同? -
这个方法很有趣,但是随着编辑,这个问题变成了一个彻头彻尾的广告。您的方法的主要弱点是
switch语句在词法上没有绑定到您的 case 语句,如果由于某种原因,switch与其case块断开连接,这将导致一些非常奇怪的行为。显而易见的解决方案是将switch做成上下文管理器,这样用户就可以做with switch(x):\n...if case(val):\n......。 -
标准选择/大小写不同是常规 if 的特殊情况。这是将相同的值与各种情况进行多次比较的情况。 select/case 的一个争论的好处是您不需要一遍又一遍地重复相同的“如果 x==”... 的东西。示例:如果 case(1, contains_in(range(10,20)),21,31,41) ... 在传统的 if 中,这将显示为“如果 x==1 或 x 在范围 (10,20) 或 x 中==21 或 x==31,或 x==41"。这个case比较简洁,嗯,case。
-
> 你能做嵌套开关吗? >> 是的,我在 github.com/jerfelix/switch_case/blob/master/… 中的第 578 行到第 697 行的示例中介绍了这一点
标签: python case switch-statement