1

の例外を別々に処理する推奨方法は、例外の原因の違いに基づいて同じタイプに基づいていますか?例外処理:Pythonの同じエラーのインスタンスを区別する

さんは異なりAttributeErrorに、次の2つのインスタンスを処理するための1つの欲求を言ってみましょう:同時に

  • 'str' object has no attribute 'append'
  • 'float' object has no attribute 'append'

、我々は他の属性のエラーを処理する必要はありません。

すべての例外タイプに共通する一般的な回答はありますか?例外オブジェクトのいくつかのメソッドまたは関数を使用して詳細について例外オブジェクトを調べることはできますか?

Try: 
    blah 
Except AttributeError as exc: 
    if exc.baz('foo') is bar: 
     handle 'str' object has no attribute 'append' 
    elif plugh(exc): 
     handle 'float' object has no attribute 'append' 
    else: 
     raise exc 

明らかな答えがリファクタリングであると仮定します。私の質問は、それが効率的でないか、単純に不可能な場合(特にそのようなケースがある場合)を特に考慮しています。

答えて

1

dirを使用すると、オブジェクトにあるメソッドと属性を確認できます。我々は唯一のargswith_tracebackを残し、dunderを望んでいないので、我々がテストすることができ、物事を絞り込む

['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'with_traceback'] 

:からのPython 3.6では

、:

a = 'hello' 
try: 
    a.append(2) 
except AttributeError as e: 
    print(dir(e)) 

あなたが得ます。あなたが得ることができる最高のものは、タプルで文字列を返すargsを使用することです。

a = 'hello' 
try: 
    a.append(2) 
except AttributeError as e: 
    if 'str' in e.args[0]: 
     print('Need to handle string') 
    elif 'float' in e.args[0]: 
     print('Need to handle float') 
+0

これは私が恐れていることです。私は早く利用可能な属性を使いこなそうとしました。 '.args'の文字列はバージョンに依存しており、将来変更される可能性があるので、文字列を使用することはお勧めできません。 1つ、たぶん、素朴な質問@roganjosh:どうしてあなたは手動でdunderメソッドを呼び出せませんか?また、私はすぐにあなたの答えを受け入れるだろうが、誰かが何か他のものを思いついた場合にはもうちょっと待っていたい。 – Lucubrator

+1

@Lucubrator例外をサブクラス化する場合は、必要に応じてオーバーライドするためのdunderメソッドが実際に用意されています。私はこれを自分自身で調べ始めましたが、カスタム例外の中に 'if' /' elif'をパッケージ化して自己処理の例外を作成しようとしていたことに気付きました。それは無意味なものです(私は方法を見つけることができなかった'args'文字列にアクセスします)。 'print(e .__ cause __)'を試してください。待つことについての心配はありません、私は興味深い質問を見つけましたので、私はそれを私の学習にも使用しました:) – roganjosh

+1

@Lucubratorそしてあなたは望むなら手動でdunderメソッドを呼び出すことができます。最後のコメントで 'print(e .__ cause __())'を意味しましたが、今編集できません。 REPLでは 'a = 'hello''を実行し、' a .__ str __() 'を実行することができます。これは' print(a) 'のようなものです。 – roganjosh