設計 - python 例外 調べる




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

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

これを行う:

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

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

ベストプラクティス

これを現在のPythonと前方互換性のある方法で行うには、例外をコンマで区切り、カッコで囲んで、例外インスタンスを変数名に割り当てた以前の構文と区別する必要があります。コンマ。

簡単な使い方の例を次に示します。

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

私はバグを隠すことを避けるためにこれらの例外だけを指定しています。

これはここに記載されています: https://docs.python.org/tutorial/errors.html : https://docs.python.org/tutorial/errors.html

変数に例外を割り当てることができます( eは一般的ですが、長い例外処理がある場合はより冗長な変数を使用する方が良いかもしれません)。インスタンスには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

Python 3.4で利用可能な抑止コンテキストマネージャを使用し excepttryexceptpass行を1行で扱うことができます:

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

しかし、私が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つの異なる例外をキャッチする私の努力は、必ずしも達成されません。

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


Python 2.7のドキュメントには、

tryステートメントには、複数のexcept句があり、異なる例外に対してハンドラを指定できます。 たった1つのハンドラが実行されます。 ハンドラは、対応するtry節で発生する例外のみを処理し、同じtry文の他のハンドラでは処理しません。 except節は、複数の例外をカッコで囲まれたタプルとして指定することができます。

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

ValueError、e:を除いて、通常はValueErrorをeとして書かれたものに使用される構文であるため、このタプルの周りのかっこは必須であることに注意してください。 古い構文は下位互換性のために引き続きサポートされています。 これは、RuntimeErrorを除いて、TypeErrorはexcept(RuntimeError、TypeError):と同等ではありませんが、RuntimeErrorをTypeErrorとして除外します。これはあなたが望むものではありません。


Pythonのドキュメントから- > 8.3例外の処理

tryステートメントには、複数のexcept句があり、異なる例外に対してハンドラを指定できます。 たった1つのハンドラが実行されます。 ハンドラは、対応するtry節で発生する例外のみを処理し、同じtry文の他のハンドラでは処理しません。 except節は、複数の例外をカッコで囲まれたタプルとして指定することができます。

except (RuntimeError, TypeError, NameError):
    pass

ValueError, e:を除いてValueError, e:通常はexcept ValueError as e:書かれたものに使用される構文であるため、このタプルの周りのかっこは必須であることに注意してください。 古い構文は下位互換性のために引き続きサポートされています。 これはexcept RuntimeError, TypeErrorexcept RuntimeError, TypeErrorexcept (RuntimeError, TypeError):と同等ではありませんが、 except RuntimeError as TypeError: except RuntimeError as TypeError:これはあなたが望むものではありません。


Pythonドキュメンテーションから:

except節は、複数の例外をカッコで囲まれたタプルとして指定することができます

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

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

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

コンマで変数と例外を区切ることは、Python 2.6と2.7では引き続き機能しますが、現在は推奨されておらず、Python 3では機能しません。 今あなたはasを使っasいるはずです。


多数の例外を頻繁に使用する場合、タプルをあらかじめ定義することができます。したがって、タプルを何度も再入力する必要はありません。

#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()で定義し、必要な場所に渡してください...





exception-handling