2016-07-12 13 views
1

例外がプログラムの最上位レベルにスタックしている間に複数の例外をキャッチしないようにする方法はありますか?複数の例外のキャッチを防ぐ方法

def try_except_block(smthg): 
    try: 
    smthg.run() 
    except Exception as e: 
    print("WRONG") 
    raise e 

def re_call(): 
    f2 = Foo(True) # will throw an exception 
    try_except_block(f2) 

class Foo: 
    def __init__(self, t): 
    self.throw = t 
    def run(self): 
    if self.throw: 
     raise KeyError 
    else: 
     re_call() 

if __name__ == '__main__': 
    f = Foo(False) # won't throw an exception 
    try_except_block(f) 

が出力:

WRONG 
WRONG 
Traceback (most recent call last): 
    File "exception_loosing_args.py", line 26, in <module> 
    try_except_block(f) 
    File "exception_loosing_args.py", line 9, in try_except_block 
    raise e 
    File "exception_loosing_args.py", line 6, in try_except_block 
    smthg.run() 
    File "exception_loosing_args.py", line 22, in run 
    re_call() 
    File "exception_loosing_args.py", line 13, in re_call 
    try_except_block(f2) 
    File "exception_loosing_args.py", line 9, in try_except_block 
    raise e 
    File "exception_loosing_args.py", line 6, in try_except_block 
    smthg.run() 
    File "exception_loosing_args.py", line 20, in run 
    raise KeyError 
KeyError 

私は一度だけ "WRONG" 印刷したいと思います。ここ

は、現象を説明非常に簡略化されたコードの例です。

私のソフトウェアでは、try_except_block関数がオブジェクトにラップされています。このオブジェクトの属性を設定するアイデアがありました。これは、例外ステートメントに「既にアクセスしました」とフラグを立てる可能性があります。私は、この考え方によって導かれる可能性のある副作用のために、この考えが気に入らない。他にはありますか?私が考えていたものの

exemple(クラス属性がグローバル変数flagでエミュレートされた):

flag = False 

def try_except_block(smthg): 
    global flag 
    try: 
    smthg.run() 
    except Exception as e: 
    if not flag: 
     print("WRONG") 
     flag = True 
    raise e 

def re_call(): 
    f2 = Foo(True) # will throw an exception 
    try_except_block(f2) 

class Foo: 
    def __init__(self, t): 
    self.throw = t 
    def run(self): 
    if self.throw: 
     raise KeyError 
    else: 
     re_call() 

if __name__ == '__main__': 
    f = Foo(False) # won't throw an exception 
    try_except_block(f) 

出力:

WRONG 
Traceback (most recent call last): 
    File "exception_loosing_args.py", line 28, in <module> 
    try_except_block(f) 
    File "exception_loosing_args.py", line 11, in try_except_block 
    raise e 
    File "exception_loosing_args.py", line 6, in try_except_block 
    smthg.run() 
    File "exception_loosing_args.py", line 24, in run 
    re_call() 
    File "exception_loosing_args.py", line 15, in re_call 
    try_except_block(f2) 
    File "exception_loosing_args.py", line 11, in try_except_block 
    raise e 
    File "exception_loosing_args.py", line 6, in try_except_block 
    smthg.run() 
    File "exception_loosing_args.py", line 22, in run 
    raise KeyError 
KeyError 
+0

例外を 'except'で再発生しないと、伝播が停止します... –

+0

動作は論理的に正しいですが、2つのネストされた' try..except'ブロックは両方とも例外を捕捉して再発生し、したがってメッセージを2回トリガします。おそらく、あまり回想されていない再帰的なロジックを使うことは、ここで最善の "修正"でしょうか? – deceze

+0

ありがとうございます。ジョン・クレメンツ:私は、他の目的のためにプログラムのトップレベルをつかむために例外が必要です。私は例外を伝播しなければならない:ここにジレンマがある。 @deceze:できません。このコードは、グラフのノードの再帰的訪問に関係しています。 –

答えて

2

あなたのコードはありませんなぜ私は完全には理解していませんそれは何ですか、あなたができることはありません。スーツは、グローバルフラグを設定するのではなく、既に見られている例外オブジェクトをマークすることです。これと同じように:

def try_except_block(smthg): 
    try: 
     smthg.run() 
    except Exception as e: 
     if not hasattr(e, "teb_already_seen"): 
      setattr(e, "teb_already_seen", True) 
      print("WRONG") 
     raise e 

そうすれば、try_except_blockによって行わ余分な処理は一度だけおそらくあなたが望むものである例外オブジェクト、あたりが起こるのだろう。

+0

これはまさに私が気づいた副作用を防ぐためのものです。ありがとうございました –

関連する問題