2013-02-05 60 views
0

可能重複:
Replacements for switch statement in python?重寫Python中切換到一個更緊湊的方式

假設我有一個Python列表:

名單=( '添加', 'SUB','PUSH','POP')

我想根據輸入運行一個函數,並且該輸入可以是列表中的任何值。

而不是寫在list中的每個元素的switch case語句,是否有更緊湊的方式來編寫它?

我的推理是針對未來列表增長的情況。

+0

在這裏看到:http://stackoverflow.com/q/60208/562139 – scorpiodawg

+1

順便說一句,你不應該調用一個變量'list',因爲這是內建'list'類型的名字。 (在這種情況下更令人困惑,因爲你的對象不是'list',它是'tuple'。) – abarnert

+0

感謝您的澄清。這麼多語言來自這麼多語言...... waaaah! – drum

回答

5

那麼,在Python中沒有開關/ 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) 
+0

+1,打我吧。 –

+1

@Lattyware:你有一些很好的額外解釋,我會偷,以改善我的答案。 – abarnert

+0

而不是提高錯誤找不到密鑰,它會工作到默認x? – drum

0

嗯,在Python中沒有switch語句。我想你的意思是一個if: ... elif:種鏈。

list_ = ('ADD', 'SUB', 'PUSH', 'POP') 
callables = {'ADD': f_add, 'SUB': f_sub, 'PUSH': f_push, 'POP': f_push} 

然後你會打電話像功能:在你情我願一個可調用函數對象與每個名稱,使用字典相關聯,因爲陰影

thing = list_[2] 
callables[thing]() 

不要將其命名變量list內置的名稱。

0

你也可以使用一個模式像這樣(有急事所以不能清理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