web-dev-qa-db-ja.com

1行に複数の例外をキャッチ(ブロックを除く)

私はできることを知っています:

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

しかし、2つの異なる例外の中で同じことをしたいのであれば、今考えることができるのはこれを行うことです。

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

したがって、2つの異なる例外をキャッチしようとする私の努力は正確には実現しません。

これを行う方法はありますか?

2293
inspectorG4dget

からPythonドキュメント

Except節は、複数の例外を括弧付きのTupleとして指定できます。例えば、

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

または、Python 2の場合のみ:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

カンマを使用して例外を変数から分離することは、Python 2.6および2.7でも機能しますが、現在は推奨されておらず、Python 3では機能しません。今、あなたはasを使うべきです。

3130
bernie

1行に複数の例外を捕捉するにはどうすればよいですか(ブロックを除く)

これを行う:

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

エラーオブジェクトを名前に割り当てるためにコンマを使用していた古い構文のため、括弧が必要です。代入にはasキーワードを使用します。エラーオブジェクトには任意の名前を使用できます。個人的にはerrorをお勧めします。

ベストプラクティス

現在のPythonとの互換性のある方法でこれを実行するには、Exceptionをカンマで区切り、それらを括弧で囲んで、例外タイプを変数名に割り当てた以前の構文と区別して、コンマ。

これが簡単な使い方の例です。

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

バグを隠さないためにこれらの例外だけを指定しています。

これはここに文書化されています: https://docs.python.org/tutorial/errors.html

例外を変数に割り当てることができます(eが一般的ですが、長い例外処理がある場合、または自分のIDEのみが選択範囲を強調する場合は、より冗長な変数を使用することをお勧めします)。 instanceはargs属性を持ちます。これが一例です。

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

Python 3では、errブロックが終了するとexceptオブジェクトは範囲外になります。

廃止予定

あなたは、エラーをコンマで割り当てるコードを見るかもしれません。この使用法は、Python 2.5以前で利用可能な唯一の形式であり、推奨されていません。Python3でコードに前方互換性を持たせるには、新しい形式を使用するように構文を更新する必要があります。

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

tryexceptpass行は、Python 3.4で使用可能な 抑制コンテキストマネージャを使用して1行で処理できます。

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

そのため、特定の例外でpassを使用したい場合は、suppressを使用してください。

243
Aaron Hall

Python 2.5以前のバージョンの場合、正しい構文は次のとおりです。

except (IDontLikeYouException, YouAreBeingMeanException), e:
    print e

eはExceptionインスタンスです。

54
schurlix

From Pythonドキュメント - > 8.3例外処理

tryステートメントは、異なる例外に対するハンドラを指定するために、1つ以上のexcept節を持つことができます。最大1つのハンドラが実行されます。ハンドラは、対応するtry句で発生した例外のみを処理し、同じtry文の他のハンドラでは処理しません。 except節は、複数の例外を括弧付きのTupleとして指定することができます。例えば:

except (RuntimeError, TypeError, NameError):
    pass

ValueError, e:以外は、現代のPythonではexcept ValueError as e:として通常書かれているものに使用されている構文であるため、このTupleを括弧で囲む必要があることに注意してください(後述)。古い構文は後方互換性のためにまだサポートされています。これはexcept RuntimeError, TypeErrorexcept (RuntimeError, TypeError):と同等ではなく、except RuntimeError asTypeError:と同等であることを意味します。

40
fedorqui

頻繁に多くの例外を使用するのであれば、Tupleを事前に定義することができます。そのため、それらを何度も再入力する必要はありません。

#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. もしあなたが、また、事前に定義されたタプルの中でそれら以外の例外を捕らえる必要があるならば、あなたは別のexceptブロックを定義する必要があるでしょう。

  2. グローバル変数を許容できない場合は、main()で定義して必要な場所に渡してください。

25
whitebeard

これを行う方法の1つは..です。

try:
   You do your operations here;
   ......................
except(Exception1[, Exception2[,...ExceptionN]]]):
   If there is any exception from the given exception list, 
   then execute this block.
   ......................
else:
   If there is no exception then execute this block. 

もう1つの方法は、exceptブロックによって実行されるタスクを実行するメソッドを作成し、それをあなたが書いたすべてのexceptブロックを通して呼び出すことです。

try:
   You do your operations here;
   ......................
except Exception1:
    functionname(parameterList)
except Exception2:
    functionname(parameterList)
except Exception3:
    functionname(parameterList)
else:
   If there is no exception then execute this block. 

def functionname( parameters ):
   //your task..
   return [expression]

2番目の方法がこれを実行するのに最適な方法ではないことを私は知っていますが、私はこのことを行う方法をいくつか示しています。

8
M.Usman

Python 2.7ドキュメントには次のように記載されています。

Tryステートメントには、さまざまな例外に対するハンドラーを指定するために、1つ以上のexcept節を含めることができます。最大1つのハンドラが実行されます。ハンドラは、対応するtry句で発生した例外のみを処理し、同じtry文の他のハンドラでは処理しません。 except節は、複数の例外を括弧付きのTupleとして指定することができます。例えば:

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

現代のPythonでは、ValueError、e:を除いて、e:としてValueErrorを除いて通常記述されている構文で、このTupleを括弧で囲む必要があります。古い構文は後方互換性のためにまだサポートされています。つまり、RuntimeErrorを除いて、TypeErrorはexcept(RuntimeError、TypeError):と同等ではありませんが、RuntimeErrorをTypeErrorとして除外することとは同等ではありません。

7
anand tripathi