2016-10-08 8 views
2

Python 3には、例外を再発行するためのuseful raise ... from ... featureがあります。つまり、発生した例外から元の(再発生した)例外をどのように見つけることができますか?ここで私はそれが発生した例外の__cause__属性にありますPython 3でre-raised例外にアクセスするには?

def some_func(): 
    try: 
     None() # TypeError: 'NoneType' object is not callable 
    except as err: 
     raise Exception("blah") from err 

try: 
    some_func() 
except as err: 
    # how can I access the original exception (TypeError)? 
+0

BTW: 'from'を使うことは、' TypeError'を非表示にしてそれをunaccesibleにするようにPythonに指示するNone''から例外Exception( "blah")を行うときに最も有用です。 *デフォルトでは、 'TypeError'は既に新しい例外に格納されています(そのため、トレースバックで'上記の例外の処理中に 'が表示される)ので、' raise ... from err'を実行することはほとんど役に立ちません。 – Bakuriu

答えて

3

をmean--何実証するコメントを(愚かな)例です。 docs on the raise statementから取られたそれはraise ... from ...についてこう述べています。

from句が例外チェーンに使用されます。与えられた場合、第二の発現は、その後のように発生した例外に添付されます別の例外クラスまたはインスタンス、でなければなりません__cause__属性(書き込み可能)。発生した例外が処理されない場合は、両方の例外が出力されます。

だから、あなたの特定のシナリオでは、repr__cause__属性をINGの:

def some_func(): 
    try: 
     None() # TypeError: 'NoneType' object is not callable 
    except TypeError as err: 
     raise Exception("blah") from err 

try: 
    some_func() 
except Exception as er: 
    print(repr(er.__cause__)) 

は、プリントアウトします:

例外が例外ハンドラから上がるたび
TypeError("'NoneType' object is not callable",) 
1

except句を)、元の例外は新しい例外の__context__に適用されます。

from構文を使用して例外が発生した場合、fromで指定された例外は新しい例外の__cause__属性に保存されます。元の例外を含む__cause____context__両方になる通常の使用の場合、

try: 
    raise Exception('first exception') 
except Exception as e: 
    raise Exception('second exception') 

及び例:ここ

def f(): 
    try: 
     raise Exception('first exception') 
    except Exception as e: 
     raise Exception('second exception') from e 

try: 
    f() 
except Exception as e: 
    print('This exception', e) 
    print('Original exception', e.__context__) 
    print('Also original exception', e.__cause__) 

__context__が設定されている場合の例でありますof __cause__の場合:

e = Exception('first exception') 
raise Exception('second exception') from e 
+0

ああ、きちんとしている。 '__context__'について知らなかった。 –

関連する問題