将Python的switch重写为更简洁的方式

0 投票
2 回答
556 浏览
提问于 2025-04-17 14:46

可能重复的问题:
在Python中,switch语句的替代方案是什么?

假设我在Python中有一个列表:

list = ('ADD', 'SUB', 'PUSH', 'POP')

我想根据输入的值来运行一个函数,而这个输入可以是列表中的任何一个值。

与其为list中的每个元素写一个switch case语句,有没有更简洁的写法呢?

我这么想是因为将来这个列表可能会增加更多的元素。

2 个回答

0

你也可以使用这样的模式(我现在有点急,没时间整理了):

>>> class Test(object):
...     def test_FOO(self):
...             print 'foo'
...     
...     def test_BAR(self):
...             print 'bar'
... 
>>> def run_on(cls, name):
...     getattr(cls, 'test_%s' % name)()
... 
>>> run_on(Test(), 'FOO')
foo
5

其实,Python里没有switch/case这种语句。

如果你的列表很小,可以用 ifelif 来处理:

def do_stuff(x, *args):
    if x == 'ADD':
        return do_add(*args)
    elif x == 'SUB':
        return do_sub(*args)
    # …
    else:
        raise RuntimeError('Never heard of {}'.format(x))

如果列表比较大,建议把每个情况都写成一个函数(我之前已经假设了这一点,如果你的代码是 return args[0] + args[1],那你就得把它改成一个叫 do_add 的函数),然后创建一个 dict,把名字和函数对应起来:

func_map = {'ADD': do_add, 'SUB': do_sub, … }

def do_stuff(x, *args):
    try:
        return func_map[x](*args)
    except KeyError:
        raise RuntimeError('Never heard of {}'.format(x))

这样做是可行的,因为在Python中,函数和其他对象一样,都是普通的对象,可以随意传递。所以,你可以把它们存储在 dict 中,从 dict 中取出来,然后继续调用。

顺便说一下,这些内容在 常见问题解答中也有解释,还有一些额外的内容。

如果你有一个默认的函数想要调用,而不是抛出错误,使用 if/elif/else 的方式很明显,但用 dict 来实现又该怎么做呢?你可以把默认函数放在 except 块里,但其实有更简单的方法:直接使用 dict.get 方法:

def do_stuff(x, *args):
    return func_map.get(x, do_default)(*args)

撰写回答