不同於我用過的其它程式語言,Python 沒有 switch / case 語句。為了實現它,我們可以使用字典對映:
1 2 3 4 5 6 7 |
def numbers_to_strings(argument): switcher = { 0: "zero", 1: "one", 2: "two", } return switcher.get(argument, "nothing") |
這段程式碼類似於:
1 2 3 4 5 6 7 8 9 10 11 12 |
function(argument){ switch(argument) { case 0: return "zero"; case 1: return "one"; case 2: return "two"; default: return "nothing"; }; }; |
Python 程式碼通常比處理 case 的標準方法更為簡短,也可以說它更難理解。當我初次使用 Python 時,感覺很奇怪並且心煩意亂。而隨著時間的推移,在 switch 中使用字典的 key 來做識別符號變得越來越習以為常。
函式的字典對映
在 Python 中字典對映也可以包含函式或者 lambda 表示式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
def zero(): return "zero" def one(): return "one" def numbers_to_functions_to_strings(argument): switcher = { 0: zero, 1: one, 2: lambda: "two", } # Get the function from switcher dictionary func = switcher.get(argument, lambda: "nothing") # Execute the function return func() |
雖然 zero
和 one
中的程式碼很簡單,但是很多 Python 程式使用這樣的字典對映來排程複雜的流程。
類的排程方法
如果在一個類中,不確定要使用哪種方法,可以用一個排程方法在執行的時候來確定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class Switcher(object): def numbers_to_methods_to_strings(self, argument): """Dispatch method""" # prefix the method_name with 'number_' because method names # cannot begin with an integer. method_name = 'number_' + str(argument) # Get the method from 'self'. Default to a lambda. method = getattr(self, method_name, lambda: "nothing") # Call the method as we return it return method() def number_0(self): return "zero" def number_1(self): return "one" def number_2(self): return "two" |
很靈活,對吧?
官方說明
官方的解釋說,“用if... elif... elif... else
序列很容易來實現 switch / case 語句”。而且可以使用函式字典對映和類的排程方法。
可以說官方的說明並沒有解釋什麼,只是給出瞭解決方案。換句話說,沒有回答為什麼。我認為其實官方真正想說的是:“Python 不需要 switch / case 語句”。
真的是這樣嗎?
是的。但是還有別的原因。我聽牛人說過,在程式碼中 switch/case 語句真的很難除錯。
就我個人而言,我發現當執行到大量巢狀的用作程式碼分支對映的字典裡,上述說法就站不住腳了。想想吧,一個超過100條語句的巢狀字典,和一個巢狀100個以上 case 的 switch/case 程式碼塊一樣,都是難以除錯的。
字典對映執行更快?
Python 沒有 case 語句,使用其它語言的衡量標準是沒有意義的,因為在某種語言中執行更快並不意味著在另一種語言中也一樣。讓我們繼續。
Python 實現方法的顯著優點
有時候我會遇到 Python 的實現方法比 switch/case 語句更好用的情況,例如在執行的時候,需要從對映裡新增或者刪除一些潛在的選項。每當這時,多年來使用字典對映和排程方法的實踐讓我受益匪淺。現在我覺得,我再也無法回到依賴 switch/case 語句的日子了。
結束語
Python 迫使我積累了很多對映的實踐經驗,對我來說是塞翁失馬,焉知非福。沒有 switch/case 語句可用的約束,促使我想到了可能不會用來開發的方法和主意。
有意或無意中,Python 沒有 switch/case 語句已成為一種社會建構,並讓我成為一個更優秀的程式設計師。
綜上所述,所以我認為這種意外的社會構建解釋比官方的“用這個來代替”的說明要好得多。