2016-08-20 96 views
2

我正在嘗試使用Python缺乏switch語句,並通過使用字典使代碼更高效,但我無法完全獲得所需內容。這裏是我工作的代碼的簡化版本Trigger Break關鍵字使用詞典Python

def zero(): 
    print("Yo") 


def one(): 
    print("Hey") 

options = { 
    0: zero, 
    1: one, 
} 
while True: 
    response = int(input("Number: ")) 
    try: 
     options.get(response)() 
    except TypeError: 
     print("Not a valid response") 

什麼,我想看到的是一些方法來打破循環,如2: break即退出循環。目前我使用sys.exit(0),但不知道是否有可能使用關鍵字break

+0

哪種語言,你比較,當你說「湊合用Python的缺乏switch語句的」?在C/C++ switch語句中,你會遇到類似的問題:'break'只會退出switch語句,並且需要其他方式來退出循環(請參閱http://stackoverflow.com/questions/對的一 - 環 - 從-內部-A-開關如何致斷出)1420029 /。 –

回答

2

你可以在循環定義LoopBreak例外,養在一個two功能,並趕上它break

class LoopBreak(Exception): 
    pass  

def zero(): 
    print("Yo") 

def one(): 
    print("Hey") 

def two(): 
    raise LoopBreak 

options = { 
    0: zero, 
    1: one, 
    2: two 
} 

while True: 
    response = int(input("Number: ")) 
    try: 
     options.get(response)() 
    except TypeError: 
     print("Not a valid response") 
    except LoopBreak: 
     break 

作爲關注點,這類似於使用的模式由Python自行停止生成器;當它們的數值用完到yield時,它們會引發StopIteration異常。

編輯:正如@ mfripp在下面正確註釋,這將掩蓋在執行zeroone期間引發的任何TypeError。我會改變主循環這個不是(這樣你就不必依靠TypeError):

while True: 
    response = int(input("Number: ")) 
    action = options.get(response) 
    if action is None: 
     print("Not a valid response") 
     continue 
    try: 
     action() 
    except LoopBreak: 
     break 
0

這就是你需要:

while True: 
    response = int(input("Number: ")) 
    if response not in options: 
     print("Not a valid response") 
    else if response == 2: 
     break 
    else: 
     options[response]() # invoke the corresponding function 

順便說一句,在字典存儲功能並且具有像這樣調用它們並不完全是Pythonic。用連續的if簡單明確地列舉出你需要的行爲就好多了。

+0

是的,這部分工作,但我正在尋找一種方式退出循環。 – MANA624

+0

好的,謝謝。你認爲我應該丟掉字典並堅持一堆if和elif語句嗎? – MANA624

+1

@ MANA624我在實踐中發現,if-else只是簡化了閱讀代碼。使用字典通常最適合_data_,並且仍然可以使用字典來存儲函數,但是在實踐中我發現,在代碼維護方面,顯式枚舉實際上是一件非常好的事情。 –

1

有幾種方法可以做到這一點。

這裏的@ BingsF的聰明的答案(這人會不會掩蓋所選擇的功能內引發的異常),一個更強大的版本:

class LoopBreak(Exception): 
    pass  

def zero(): 
    print("Yo") 

def one(): 
    print("Hey") 

def two(): 
    raise LoopBreak 

options = { 
    0: zero, 
    1: one, 
    2: two 
} 

while True: 
    try: 
     response = int(input("Number: ")) 
     action = options[response] 
    except (ValueError, KeyError): 
     print("Not a valid response") 
     continue 

    try: 
     action() 
    except LoopBreak: 
     break 

或者你可以指定你的字典裏一個特殊的標誌,這將迫使一個破解:

def zero(): 
    print("Yo") 

def one(): 
    print("Hey") 

options = { 
    0: zero, 
    1: one, 
    2: False 
} 

while True: 
    try: 
     response = int(input("Number: ")) 
     action = options[response] 
    except (ValueError, KeyError): 
     print("Not a valid response") 
     continue 

    if action is False: 
     break 
    else: 
     action() 

或者使用一個特殊的返回值來強制終止:

def zero(): 
    print("Yo") 
    # returns None by default 

def one(): 
    print("Hey") 
    # returns None by default 

def two(): 
    return False 

options = { 
    0: zero, 
    1: one, 
    2: two 
} 

while True: 
    try: 
     response = int(input("Number: ")) 
     action = options[response] 
    except (ValueError, KeyError): 
     print("Not a valid response") 
     continue 

    if action() is False: 
     break 

下面的代碼可能更「Pythonic」。它可能比上面的方法慢得多,因爲它必須檢查所有的if語句,而不是通過散列在字典中查找函數。但它可能更易於閱讀和維護。

while True: 
    try: 
     response = int(input("Number: ")) 
    except ValueError: 
     response = -1 # error flag 

    if response == 0: 
     print("Yo") 
    elif response == 1: 
     print("Hey") 
    elif response == 2: 
     break 
    else: 
     print("Not a valid response")