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

时间:2011-03-26 07:33:07

标签: python case switch-statement

最近,我在网上看到了一些关于如何在Python中没有好的“切换/案例”等问题的讨论。我意识到有几种方法可以做类似的事情 - 一些是lambda,一些是字典。关于替代方案,还有其他StackOverflow讨论。甚至有两个PEP(PEP 0275和PEP 3103)讨论(并拒绝)将开关/案例整合到语言中。

我提出了我认为切换/案例的优雅方式。

最终看起来像这样:

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)可以检查“等于”以外的比较        (例如案例(less_than(1000))     3)比字典方法更可读,并且可能是/ elif方法
    4)可以跟踪有多少真实案例     5)可以限制允许的真实案例数量。 (即执行        前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]

如果同一个开关一遍又一遍地重复,则可以节省很多时间。不确定用例的频繁程度,但似乎某些情况下这是有道理的。

github上的示例文件有更多示例。

6 个答案:

答案 0 :(得分:6)

  

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

没有

  

你对改善它有什么建议吗?

是。不要打扰。它节省了什么?真的吗?通过从每个x条件中删除变量elif,您实际上已经使代码更多变得模糊。另外,通过将elif替换为if你已经为所有Python程序员创建了故意混淆,他们现在认为这些案例是独立的。

这会造成混乱。

  

如果同一个开关一遍又一遍地重复,则可以节省很多时间。不确定用例的频繁程度,但似乎某些情况下这是有道理的。

没有。这是非常罕见的,非常人为的,非常难以阅读。查看所涉及的实际变量至关重要。删除变量名会使事情有意混淆。现在我必须找到拥有switch()函数来解释case

当有两个或更多变量时,这会完全崩溃。

答案 1 :(得分:4)

在Stackoverflow上有过多的讨论可以解决这个问题。您可以使用顶部的搜索功能查找其他一些讨论。

但是,我没有看到你的解决方案比基本词典更好:

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

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

答案 2 :(得分:4)

恕我直言,switch statement存在的主要原因是它可以被翻译/编译成(非常快)jump table。您提议的实施将如何实现这一目标?正如其他海报所展示的那样,今天Python的词典就是这样做的。

其次,我认为switch语句可能比某些语言中的替代语言更清晰,但在python的情况下,我认为if / elif / else在清晰度上获胜。

答案 3 :(得分:3)

我一直只是使用词典,if / elses或lambdas来表示我的切换语句。阅读你的代码tho =)

<强>文档:

why-isn-t-there-a-switch-or-case-statement-in-python

答案 4 :(得分:3)

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的发展方向。我只是厌倦了一遍又一遍地写它们,所以我写了一个类和一些装饰来为我处理它。

答案 5 :(得分:0)

2021 年更新:match-case 在 Python 3.10 中引入

这个激烈争论的话题现在可以结束了。

事实上,将在 Python 3.10 发布的 October 2021 引入了 structural pattern matching,它为语言带来了 match-case 构造。

有关详细信息,请参阅 this related answer