【问题标题】:Rewriting Python switch into a more compact way [duplicate]将Python开关重写为更紧凑的方式[重复]
【发布时间】:2013-01-19 20:49:54
【问题描述】:

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

假设我有一个 Python 列表:

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

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

除了为list中的每个元素编写switch case语句,还有更简洁的编写方式吗?

我的理由是列表在未来增长的情况。

【问题讨论】:

  • 顺便说一句,你不应该调用变量list,因为这是内置list类型的名称。 (在这种情况下更令人困惑,因为您的对象不是list,而是tuple。)
  • 感谢您的澄清。来自这么多语言的这么多术语......哇哦!

标签: python switch-statement


【解决方案1】:

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

【讨论】:

  • @Lattyware:你有一些很好的额外解释,我会偷来改进我的答案。
  • 不会为未找到的键引发错误,而是使用默认 x 吗?
  • @drum:当然,如果这是你想要的,你可以做到。在这种情况下,您可能希望将try/map[x]/except 替换为map.get。我会编辑答案。
【解决方案2】:

你也可以使用这样的模式(匆忙所以无法清理 atm):

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 2015-06-16
    • 1970-01-01
    • 2021-07-01
    • 2013-11-24
    • 1970-01-01
    相关资源
    最近更新 更多