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

jer*_*lix 3 python case switch-statement

最近,我在网上看到一些关于如何在Python中没有好的"switch/case"等级的讨论.我意识到有几种方法可以做类似的事情 - 一些是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")
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是:这是一个有价值的创作吗?你对改善它有什么建议吗?

我把包含文件放在github上,以及大量的例子.(我认为整个包含文件大约有50个可执行行,但我有1500行示例和文档.)我是否过度设计了这个东西,浪费了大量时间,还是有人觉得这个值得?

编辑:

试图解释为什么这与其他方法不同:
1)多个路径是可能的(执行两个或更多个案例),这在字典方法中更难.
2)可以检查除"equals"以外的比较(例如case(less_than(1000)).
3)比字典方法更可读,并且可能如果/ elif方法
4)可以跟踪有多少True案例.
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.
Run Code Online (Sandbox Code Playgroud)

下面是一个示例,试图说明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]
Run Code Online (Sandbox Code Playgroud)

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

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

S.L*_*ott 6

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

没有.

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

是.不要打扰.它节省了什么?真的吗?通过从每个条件中删除变量,实际上使代码变得更加模糊.而且,通过替换明显的代码,您已经为所有Python程序员创建了故意混淆,他们现在认为这些情况是独立的.xelifelifif

这造成了混乱.

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

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

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


Rus*_*ias 5

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

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

def switch(x):
    return {
        1 : 1,
        2 : 2,
    }[x]
Run Code Online (Sandbox Code Playgroud)

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

  • 不要忘记 get() 方法。返回 { 1: 1, 2:2 }.get(x, '默认值') (3认同)

Mic*_*ent 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'
Run Code Online (Sandbox Code Playgroud)

你明白了。为什么?是的,调度表是 Python 中的最佳选择。我只是厌倦了一遍又一遍地编写它们,所以我编写了一个类和一些装饰器来为我处理它。