使用 Python 實(shí)現(xiàn)簡(jiǎn)單的 switch/case 語(yǔ)句的方法
在Python中是沒有Switch / Case語(yǔ)句的,很多人認(rèn)為這種語(yǔ)句不夠優(yōu)雅靈活,在Python中用字典來(lái)處理多條件匹配問(wèn)題字典會(huì)更簡(jiǎn)單高效,對(duì)于有一定經(jīng)驗(yàn)的Python玩家不得不承認(rèn),的確如此。
但今天我們還是來(lái)看看如果一定要用Python來(lái)Switch / Case,可以怎么玩。
語(yǔ)法約束
我們先定義一下Switch/Case應(yīng)該怎么表達(dá),為了簡(jiǎn)單我們可以讓它長(zhǎng)成這樣。
def cn(): print('cn') def us(): print('us') switch(lang).case('cn',cn) truetruetrue.case('us',us) .default(us)
類實(shí)現(xiàn)一
通過(guò)以上約束,我們可以把switch當(dāng)成一個(gè)類來(lái)實(shí)現(xiàn),傳入的參數(shù)在構(gòu)造函數(shù)里處理,然后再分別實(shí)現(xiàn)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()
在構(gòu)造函數(shù)中我們記住了 case_path 和執(zhí)行狀態(tài) _invoked ,在 case() 里如果當(dāng)前的 key 和 switch_to 匹配并且函數(shù)沒有被執(zhí)行過(guò),那么就更新 _invoked 并執(zhí)行對(duì)應(yīng)的方法。在 default() 里檢查一下 _invoked ,如果從沒執(zhí)行過(guò),那么就調(diào)用 default 分支的函數(shù)。
看上去還不錯(cuò),我們來(lái)試用一下。
switch('cn').case('cn',cn).case('us',us).default(fail) >>> cn switch('us').case('cn',cn).case('us',us).default(fail) >>> cn switch('jp').case('cn',cn).case('us',us).default(fail) >>> fail switch('cn').case('cn',cn).case('us',us) >>> cn
讓我們來(lái)看幾個(gè)奇葩一點(diǎn)的case。
# duplicate case switch('us').case('us',cn).case('us',us).default(fail) >>> cn def cn() return 'cn' def us() return 'us' # return value result = switch('cn').case('cn',cn).case('us',us) result >>> <python_switch_case.switch object at 0x11034fb70>
發(fā)現(xiàn)了沒有,上面的實(shí)現(xiàn)不會(huì)處理重復(fù)的case,當(dāng)然你可以加強(qiáng)一下case方法,最好是拋出異常,其他編程語(yǔ)言通常都這樣做。
第二個(gè)問(wèn)題,你希望從case里拿到返回值,像上面的寫法是沒希望了,因?yàn)槿拥袅?。我們可以考慮在switch類里加一個(gè)result的變量來(lái)保存執(zhí)行結(jié)果。
class switch(object): def __init__(self, case_path): ... self.result = None def case(self, key, method): ... self.result = method() ...
在調(diào)用結(jié)束后,就可以通過(guò) result 拿到結(jié)果了。
_ = switch('cn').case('cn',cn).case('us',us) _.result >>> cn
類實(shí)現(xiàn)二
我大概在網(wǎng)上搜了一下,你還可以參考 Brian Beck 通過(guò)類來(lái)實(shí)現(xiàn)Swich/Case。
class switch(object): def __init__(self, value): self.value = value self.fall = False def __iter__(self): """Return the match method once, then stop""" yield self.match raise StopIteration def match(self, *args): """Indicate whether or not to enter a case suite""" if self.fall or not args: return True elif self.value in args: self.fall = True return True else: return False c = 'z' for case in switch(c): if case('a'): pass # only necessary if the rest of the suite is empty if case('c'): pass # ... if case('y'): pass if case('z'): print("c is lowercase!") break if case('A'): pass # ... if case('Z'): print("c is uppercase!") break if case(): # default print("I dunno what c was!")
這種實(shí)現(xiàn)相對(duì)復(fù)雜一點(diǎn),而且用起來(lái)也不是很舒服,又需要for又需要if(還不如直接if/else痛快)。當(dāng)然也有好處,就是可以把相同結(jié)果的case放一起,而且case里可以寫更多東西,不僅僅是一個(gè)方法名。
寫在最后
最后我們還是回到Python推崇的方法來(lái)處理switch/case問(wèn)題,一般我們可以通過(guò)字典來(lái)處理這種多分支的問(wèn)題,舉例說(shuō)明。
MAPPING = { 'cn': cn, 'us': us } lang = 'cn' result = MAPPING.get(lang, default=us)
是不是一目了然,不僅易于閱讀也易于維護(hù)。在字典中key是唯一的,value可以是任意類型的數(shù)據(jù),可以是類或者是方法,所以足夠靈活。
下面通過(guò)代碼再次學(xué)習(xí)python語(yǔ)言switch-case
初學(xué)python語(yǔ)言,竟然很久才發(fā)現(xiàn)python沒有switch-case語(yǔ)句,查看官方文檔說(shuō)是可以用if-elseif-elseif。。。。代替。
講真,這都不是問(wèn)題。不就是一個(gè)條件判斷嗎。用if-elseif-.......肯定沒問(wèn)題,同時(shí)也用其他的解決方案,比較簡(jiǎn)單的就是利用
字典來(lái)實(shí)現(xiàn)同樣的功能。寫一個(gè)字典,每個(gè)key對(duì)應(yīng)的值是一個(gè)方法。如switch =
{"valueA":functionA,"valueB":functionB,"valueC":functionC}
調(diào)用時(shí)可以像這樣
try: switch["value"]() #執(zhí)行相應(yīng)的方法。 except KeyError as e:
pass 或 functionX #執(zhí)行default部分
簡(jiǎn)單代碼如下:
switch = { "a":lambda x:x*2, "b":lambda x:x*3, "c":lambda x:x**x } try: swtich["c"](6) except KeyError as e: pass
如果不嫌麻煩自己寫一個(gè)swtich類來(lái)實(shí)現(xiàn)也沒問(wèn)題......不過(guò)真有這個(gè)必要嗎
總結(jié)
以上所述是小編給大家介紹的使用 Python 實(shí)現(xiàn)簡(jiǎn)單的 switch/case 語(yǔ)句的方法,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
python 中的collections.OrderedDict() 用法
這篇文章主要介紹了python 中的collections.OrderedDict() 用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05Pandas DataFrame轉(zhuǎn)換為字典的方法
實(shí)際開發(fā)中我們可能會(huì)遇到一類問(wèn)題,如何將Pandas DataFrame轉(zhuǎn)換為字典,本文就來(lái)介紹一下,感興趣的可以了解一下2021-05-05對(duì)Python _取log的幾種方式小結(jié)
今天小編就為大家分享一篇對(duì)Python _取log的幾種方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07Python數(shù)據(jù)類型詳解(四)字典:dict
本文給大家分享的知識(shí)是Python數(shù)據(jù)類型中的字典(dict)的基本概念,常用操作以及示例,非常的實(shí)用,對(duì)于大家理解字典dict非常有幫助,希望大家能夠喜歡2016-05-05Python采集某度貼吧排行榜實(shí)戰(zhàn)示例
這篇文章主要為大家介紹了Python采集某度貼吧排行榜實(shí)戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04利用python設(shè)計(jì)圖像加密技術(shù)(Arnold算法)
這篇文章主要介紹了利用python設(shè)計(jì)圖像加密技術(shù)(Arnold算法),本文將借助Arnold置亂法,講解如何用python從頭至尾設(shè)計(jì)出一套圖像加密算法,需要的小伙伴可以才參考一下2022-03-03