Python中的Switch/Case实现有什么价值吗?

Python中的Switch/Case实现有什么价值吗?,python,case,switch-statement,Python,Case,Switch Statement,最近,我在网上看到一些关于Python中如何没有好的“switch/case”等价物的讨论。我意识到有几种方法可以做类似的事情——一些是使用lambda,一些是使用字典。还有其他关于替代方案的讨论。甚至有两位政治公众人物(PEP 0275和PEP 3103)讨论(并拒绝)将switch/case集成到语言中 我想出了一个我认为是一个优雅的方法来做开关/案例 结果是这样的: from switch_case import switch, case # note the import

最近,我在网上看到一些关于Python中如何没有好的“switch/case”等价物的讨论。我意识到有几种方法可以做类似的事情——一些是使用lambda,一些是使用字典。还有其他关于替代方案的讨论。甚至有两位政治公众人物(PEP 0275和PEP 3103)讨论(并拒绝)将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文件大约有50行可执行代码,但我有1500行示例和文档。)我是否过度设计了这件事,浪费了很多时间,或者有人会觉得这是值得的

编辑:

试图解释这与其他方法不同的原因:
1) 可能有多条路径(执行两个或多个案例), 在字典法中哪个更难。
2) 可以进行“等于”以外的比较检查 (例如案例(小于(1000))。
3) 比dictionary方法更具可读性,可能还有if/elif方法
4) 可以跟踪真实案例的数量。
5) 可以限制允许的真实案例数量。(即执行 前两个真实案例…
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/elif/else:

如果(status_code==2或status_code==4或(11有过多的讨论涉及Stackoverflow上的此问题。您可以使用顶部的搜索功能查找其他一些讨论

但是,我看不出您的解决方案比基本字典更好:

def switch(x):
    return {
        1 : 1,
        2 : 2,
    }[x]

虽然,使用此方法添加默认子句并非易事。但是,您的示例似乎复制了一个复杂的if/else语句?不确定我是否会为此包含一个外部库。

我总是使用字典、if/else或lambda作为类似开关的语句。通读代码tho=)

文档:


IMHO,存在的主要原因是可以将其翻译/编译成(非常快)。您建议的实现将如何实现这一目标?正如其他海报所示,Python的字典今天就做到了这一点

第二,我猜switch语句可能比某些语言中的备选语句读得更清楚,但在python的情况下,我认为如果elif
/
elif
/
else
在清晰性方面获胜,则

所以,我的问题是:这是一个有价值的创造吗

没有

你有什么改进的建议吗

是的。不用麻烦了。它节省了什么?说真的?实际上,通过从每个
elif
条件中删除变量
x
,您已经使代码变得更加模糊。此外,通过将明显的
elif
替换为
if
,您已经为所有Python程序员故意制造了混乱,他们现在会认为cas他们是独立的

这造成了混乱

大的节省是在长if语句中,相同的切换被重复了一遍又一遍。不确定一个用例有多频繁,但似乎在某些情况下这是有意义的

不。它非常罕见,非常做作,而且很难阅读。查看所涉及的实际变量非常重要。省略变量名称会故意造成混淆。现在我必须找到所属的
switch()
函数来解释
案例

当存在两个或多个变量时,这将完全崩溃

from pyswitch import Switch   # pyswitch can be found on PyPI

myswitch = Switch()

@myswitch.case(42)
def case42(value):
    print "I got 42!"

@myswitch.case(range(10))
def caseRange10(value):
    print "I got a number from 0-9, and it was %d!" % value

@myswitch.caseIn('lo')
def caseLo(value):
    print "I got a string with 'lo' in it; it was '%s'" % value

@myswitch.caseRegEx(r'\b([Pp]y\w)\b')
def caseReExPy(matchOb):
    print r"I got a string that matched the regex '\b[Pp]y\w\b', and the match was '%s'" % matchOb.group(1)

@myswitch.default
def caseDefault(value):
    print "Hey, default handler here, with a value of %r." % value

myswitch(5)  # prints: I got a number from 0-9, and it was 5!
myswitch('foobar')  # prints: Hey, default handler here, with a value of foobar.
myswitch('The word is Python')  # prints: I got a string that matched the regex '\b[Pp]y\w\b', and the match was 'Python'

你明白了。为什么?是的,派送表是Python中的一种方式。我只是厌倦了一遍又一遍地编写它们,所以我编写了一个类和一些装饰程序来为我处理它。

更新2021:
匹配案例
在Python 3.10中引入

这个备受争议的话题现在可以结束了

事实上,将于年发布的介绍为该语言带来了
匹配case
结构


请参阅以了解详细信息。

这应该作为另一个政治公众人物提交。这与传统的
if
有何不同?这种方法很有趣,但经过编辑后,这个问题变成了一个平淡无奇的广告。你的方法的主要缺点是
switch
语句在词汇上与你的案例状态没有联系nts,无论出于何种原因,
开关
与其
大小写
块断开连接,都会导致一些非常奇怪的行为。显而易见的解决方案是将
开关
放入上下文管理器中,这样用户就可以使用开关(x):\n…if case(val):\n……
。标准的select/case是传统if的一种特殊情况。它是将相同的值与不同的情况进行多次比较的情况。select/case的一个有争议的优点是,您不需要反复重复相同的“if x=”…内容。例如:if case(1,包含在(范围(10,20)),21,31,41中)…在传统的if中,这将是“如果x==1或x在范围内(10,20)或x==21或x==31,或x==41”。在这种情况下,Case更简洁。>你能做嵌套开关吗?>>是的,我在示例中介绍了我的新switch_Case.py库的其他好处:1)多个路径是可能的(执行两个或更多的情况)。2) 可以检查除“equals”之外的比较(例如case(小于(1000)),3)比您描述的字典方法更可读。4) 可以追踪有多少真实案例。5) 可以限制允许的案例数量。6) 允许