将Python切换重写为更紧凑的方式

时间:2013-02-05 01:46:59

标签: python switch-statement

  

可能重复:
  Replacements for switch statement in python?

假设我有一个Python列表:

  

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

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

而不是为list中的每个元素编写switch case语句,是否有更紧凑的写入方式?

我的理由是这个名单将来会增长。

2 个答案:

答案 0 :(得分:5)

嗯,Python中 没有switch / case语句。

对于小list,您要使用if / elif

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))

对于较大的list,您需要确保每个案例都是一个函数(我已经假设上面这个,但是如果您有像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中检索它们,然后仍然可以调用它们。

顺便说一句,the FAQ中都解释了这一点,还有一些额外的幻想。

如果你有一些默认功能,你想打电话而不是提出错误,显然如何使用if / elif / else链来做到这一点,但是如何你用dict地图做到了吗? 可以通过将默认函数放入except块来实现,但有一种更简单的方法:只需使用dict.get方法:

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

答案 1 :(得分: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