首頁 >後端開發 >Python教學 >Python實作switch/case語句的方法

Python實作switch/case語句的方法

不言
不言原創
2018-09-18 15:21:168773瀏覽

本篇文章帶給大家的內容是關於Python實現switch/case語句的方法,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

在Python中是沒有Switch / Case語句的,很多人認為這種語句不夠優雅靈活,在Python中用字典來處理多條件匹配問題字典會更簡單高效,對於有一定經驗的Python玩家不得不承認,的確如此。

但今天我們還是來看看如果一定要用Python來Switch / Case,可以怎麼玩。

語法約束

我們先定義Switch/Case應該怎麼表達,為了簡單我們可以讓它長成這樣。

def cn():
    print('cn')

def us():
    print('us')

switch(lang).case('cn',cn)
            .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()裡如果目前的 keyswitch_to匹配且函數沒有被執行過,那麼就更新_invoked並執行對應的方法。在default()裡檢查一下_invoked,如果從沒執行過,那麼就呼叫default分支的函數。

看起來還不錯,我們來試用一下。

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

讓我們來看幾個奇葩一點的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>

發現了沒有,上面的實作不會處理重複的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。

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

這種實作相對複雜一點,而且用起來也不是很舒服,又需要for又需要if(還不如直接if/else痛快)。當然也有好處,就是可以把相同結果的case放一起,而且case裡可以寫更多東西,不只是一個方法名稱。

寫在最後

最後我們還是回到Python推崇的方法來處理switch/case問題,一般我們可以透過字典來處理這種多分支的問題,舉例說明。

MAPPING = {
    'cn': cn,
    'us': us
}

lang = 'cn'
result = MAPPING.get(lang, default=us)

是不是一目了然,不僅易於閱讀也易於維護。在字典中key是唯一的,value可以是任意類型的數據,可以是類別或方法,所以夠靈活。

以上是Python實作switch/case語句的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn