Rewriting Python switch into a more compact way

Possible Duplicate:
Replacements for switch statement in python?

Suppose I have a list in Python:

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

I want to run a function depending on input, and that input can be any value in the list.

Instead of writing a switch case statement for each element in list , is there a more compact way of writing it?

My reasoning is for the case of the list growing in the future.


Well, there is no switch/case statement in Python.

For a small list , you want to use 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))

For a larger list , you want to make sure each case is a function (I already assumed that above, but if you had code like return args[0] + args[1] , you'd have to change that into a do_add function), and create a dict mapping names to functions:

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

This works because in Python, functions are normal objects that you can pass around like any other objects. So, you can store them in a dict , retrieve them from the dict , and still call them.

By the way, this is all explained in the FAQ, along with a bit of extra fanciness.

If you have some default function you'd like to call instead of raising an error, it's obvious how to do that with the if / elif / else chain, but how do you do it with the dict map? You could do it by putting the default function into the except block, but there's an easier way: just use the dict.get method:

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

你也可以使用这样的模式(匆忙所以不能清理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
链接地址: http://www.djcxy.com/p/42762.html

上一篇: Python使用开关盒?

下一篇: 将Python切换重写为更紧凑的方式