try - python3 raise exception example




在一行中捕獲多個異常(塊除外) (5)

如何在一行中捕獲多個異常(塊除外)

做這個:

try:
    may_raise_specific_errors():
except (SpecificErrorOne, SpecificErrorTwo) as error:
    handle(error) # might log or have some other default behavior...

由於較舊的語法使用逗號將錯誤對象分配給名稱,因此必須使用括號。 as關鍵字用於分配。 您可以使用任何名稱作為錯誤對象,我個人更喜歡error

最佳實踐

要以當前和向前兼容Python的方式執行此操作,您需要使用逗號分隔異常並用括號括起它們,以區別於將異常實例分配給變量名的早期語法,方法是遵循要捕獲的異常類型逗號。

這是一個簡單用法的例子:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary
    quit(0)

我只指定了這些異常,以避免隱藏錯誤,如果遇到錯誤,我希望完整的堆棧跟踪。

這在此處記錄: https://docs.python.org/tutorial/errors.htmlhttps://docs.python.org/tutorial/errors.html

您可以將異常分配給變量( e是常見的,但如果您有長時間的異常處理,或者您的IDE僅突出顯示大於該值的選項,您可能更喜歡更詳細的變量,就像我的那樣。)該實例具有args屬性。 這是一個例子:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError) as err: 
    print(err)
    print(err.args)
    quit(0)

請注意,在Python 3中,當except塊結束時, err對象超出範圍。

棄用

您可能會看到用逗號分配錯誤的代碼。 這種用法是Python 2.5及更早版本中唯一可用的形式,不推薦使用,如果您希望代碼在Python 3中向前兼容,則應更新語法以使用新表單:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError), err: # don't do this in Python 2.6+
    print err
    print err.args
    quit(0)

如果您在代碼庫中看到逗號名稱分配,並且您使用的是Python 2.5或更高版本,請切換到新方法,以便在升級時代碼保持兼容。

suppress上下文管理器

接受的答案實際上是4行代碼,最小值:

try:
    do_something()
except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

except passexcepttry可以使用suppress 3.4中suppress上下文管理器在一行中處理:

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

因此,當您想要pass某些異常時,請使用suppress

我知道我能做到:

try:
    # do something that may fail
except:
    # do this if ANYTHING goes wrong

我也可以這樣做:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreTooShortException:
    # stand on a ladder

但如果我想在兩個不同的例外中做同樣的事情,我現在能想到的最好的就是這樣做:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreBeingMeanException:
    # say please

有什麼辦法我可以做這樣的事情(因為兩個例外的行動都是say please ):

try:
    # do something that may fail
except IDontLikeYouException, YouAreBeingMeanException:
    # say please

現在這真的不起作用,因為它符合以下語法:

try:
    # do something that may fail
except Exception, e:
    # say please

因此,我努力捕捉這兩個截然不同的例外並沒有完全實現。

有沒有辦法做到這一點?


Python 2.7文檔聲明:

try語句可能有多個except子句,以指定不同異常的處理程序。 最多將執行一個處理程序。 處理程序僅處理相應try子句中發生的異常,而不處理同一try語句的其他處理程序中的異常。 except子句可以將多個異常命名為帶括號的元組,例如:

try:
    raise ValueError("hello")
except (RuntimeError, ValueError, KeyError) as a:
    print a

請注意,這個元組周圍的括號是必需的,因為除了ValueError之外,e:是用於正常寫入的語法,除了ValueError之外,在現代Python中如下所述(如下所述)。 仍然支持舊語法以實現向後兼容性。 這意味著除了RuntimeError之外,TypeError不等同於except(RuntimeError,TypeError):但是除了RunErrorError之外還有TypeError:這不是你想要的。


如果經常使用大量異常,則可以預先定義元組,因此不必多次重新鍵入它們。

#This example code is a technique I use in a library that connects with websites to gather data

ConnectErrs  = (URLError, SSLError, SocketTimeoutError, BadStatusLine, ConnectionResetError)

def connect(url, data):
    #do connection and return some data
    return(received_data)

def some_function(var_a, var_b, ...):
    try: o = connect(url, data)
    except ConnectErrs as e:
        #do the recovery stuff
    blah #do normal stuff you would do if no exception occurred

筆記:

  1. 如果您還需要捕獲除預定義元組中的異常之外的其他異常,則需要定義另一個除塊之外的異常。

  2. 如果您無法容忍全局變量,請在main()中定義它並在需要的地方傳遞它...


對於python 2.5及更早版本,正確的語法是:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    print e

其中e是Exception實例。


Python文檔

例如,except子句可以將多個異常命名為帶括號的元組

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

或者,僅適用於Python 2:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

使用逗號將變量與變量分開仍然可以在Python 2.6和2.7中使用,但現在已棄用,但在Python 3中不起作用; 現在你應該使用as







exception-handling