在Python中是沒有Switch / Case語句的,很多人認為這種語句不夠優雅靈活,在Python中用字典來處理多條件匹配問題字典會更簡單高效,對于有一定經驗的Python玩家不得不承認,的確如此。
但今天我們還是來看看如果一定要用Python來Switch / Case,可以怎么玩。
語法約束
我們先定義一下Switch/Case應該怎么表達,為了簡單我們可以讓它長成這樣。
def cn(): print('cn')def us(): print('us')switch(lang).case('cn',cn)truetruetrue.case('us',us) .default(us)
類實現一
通過以上約束,我們可以把switch當成一個類來實現,傳入的參數在構造函數里處理,然后再分別實現case和default方法即可。
class switch(object): def __init__(self, case_path): self.switch_to = case_path self._invoked = False def case(self, key, method): if self.switch_to == key and not self._invoked: self._invoked = True method() return self def default(self, method): if not self._invoked: self._invoked = True method()
在構造函數中我們記住了 case_path 和執行狀態 _invoked ,在 case() 里如果當前的 key 和 switch_to 匹配并且函數沒有被執行過,那么就更新 _invoked 并執行對應的方法。在 default() 里檢查一下 _invoked ,如果從沒執行過,那么就調用 default 分支的函數。
看上去還不錯,我們來試用一下。
switch('cn').case('cn',cn).case('us',us).default(fail)>>> cnswitch('us').case('cn',cn).case('us',us).default(fail)>>> cnswitch('jp').case('cn',cn).case('us',us).default(fail)>>> failswitch('cn').case('cn',cn).case('us',us)>>> cn
讓我們來看幾個奇葩一點的case。
# duplicate caseswitch('us').case('us',cn).case('us',us).default(fail)>>> cndef cn() return 'cn'def us() return 'us'# return valueresult = switch('cn').case('cn',cn).case('us',us)result>>> <python_switch_case.switch object at 0x11034fb70>
發現了沒有,上面的實現不會處理重復的case,當然你可以加強一下case方法,最好是拋出異常,其他編程語言通常都這樣做。
第二個問題,你希望從case里拿到返回值,像上面的寫法是沒希望了,因為扔掉了。我們可以考慮在switch類里加一個result的變量來保存執行結果。
class switch(object): def __init__(self, case_path): ... self.result = None def case(self, key, method): ... self.result = method() ...
在調用結束后,就可以通過 result 拿到結果了。
_ = switch('cn').case('cn',cn).case('us',us)_.result>>> cn
類實現二
我大概在網上搜了一下,你還可以參考 Brian Beck 通過類來實現Swich/Case。
新聞熱點
疑難解答