2013-10-22 16 views
21

例外が発生した後tryブロックの実行に戻ることはできますか?例については (目標は以下を書くことです):python catch例外とtryブロックの継続

try: 
    do_smth1() 
    do_smth2() 
except: 
    ??? # magic word to proceed to do_smth2() if there was exception in do_smth1 
+0

中断された後は、 'try'ブロックに戻ることはできません。 –

+0

私は思っていません。構造体によっては、フローをセグメント化し、次に実行する点を指定する必要があります(このスニペットの 'do_smth2')。 – Jokester

+3

可能な複製[例外の「次の再開」のためのPythonの方法?](http://stackoverflow.com/questions/18655481/a-pythonic-way-for-resume-next-on-exceptions) –

答えて

27

try: 
    do_smth1() 
except: 
    pass 

try: 
    do_smth2() 
except: 
    pass 

いいえ、あなたはそれを行うことはできません。これは、Pythonがその構文を持つ方法です。例外のためにtryブロックを終了すると、戻ってくることはありません。

for-loopについてはどうですか?

funcs = do_smth1, do_smth2 

for func in funcs: 
    try: 
     func() 
    except Exception: 
     pass # or you could use 'continue' 

注しかしそれは裸exceptを持っている悪い習慣と見なされていること。代わりに、特定の例外を検出する必要があります。私はExceptionのために捕獲しました。それは、メソッドが投げるかもしれない例外を知らずに私ができることと同じくらい良いことです。あなたはあなたの方法を反復処理でき

+0

少なくとも例外をキャッチする例外はほとんどの例外をキャッチしますが、プログラムの最上位レベルを除いてほとんど捕捉したくないSystemExitとKeyboardInterruptを無視します – Evan

4

...

for m in [do_smth1, do_smth2]: 
    try: 
     m() 
    except: 
     pass 
1

私はあなたがこれをしたいとは思いません。一般的にtryステートメントを使用する正しい方法は、可能な限り正確です。私はそれを行うには良いだろうと思う:

try: 
    do_smth1() 
except Stmnh1Exception: 
    # handle Stmnh1Exception 

try: 
    do_smth2() 
except Stmnh2Exception: 
    # handle Stmnh2Exception 
1

どこで、どのように多くの場合、あなたがこれを行う必要があり、あなたもあなたのためにそれを行う関数を書くことができによって:

def live_dangerously(fn, *args, **kw): 
    try: 
     return fn(*args, **kw) 
    except Exception: 
     pass 

live_dangerously(do_smth1) 
live_dangerously(do_smth2) 

しかし、他のように答えは、nullを持っていることに注意してくださいexceptは、一般的にあなたのコードに間違っています。

5

あなたは望むものを達成できますが、構文は異なります。 try/exceptの後に "finally"ブロックを使用することができます。このようにすると、Pythonは例外がスローされたかどうかにかかわらず、コードブロックを実行します。

このよう

try: 
    do_smth1() 
except: 
    pass 
finally: 
    do_smth2() 

をしかし、あなたは例外がスローされなかった場合のみ)do_smth2を(実行したい場合は、 "それ以外" のブロックを使用します。

try: 
    do_smth1() 
except: 
    pass 
else: 
    do_smth2() 

あなたがそれらを混在させることができますtry/except/else/finally節でも同じです。 楽しんでください!

3

これを処理できる方法はジェネレータです。関数を呼び出す代わりに、それを生成します。発電機が失敗したならば、発電機、またはセンチネルに戻し、それを呼び出した結果を送ることができる発電機を消費しているものは何でも:上記の実現トランポリンをので、次のようになります。

def consume_exceptions(gen): 
    action = next(gen) 
    while True: 
     try: 
      result = action() 
     except Exception: 
      # if the action fails, send a sentinel 
      result = None 

     try: 
      action = gen.send(result) 
     except StopIteration: 
      # if the generator is all used up, result is the return value. 
      return result 

互換性があるでしょうジェネレータをこれで次のようになります。do_many_things()ないコールを行い

def do_smth1(): 
    1/0 

def do_smth2(): 
    print "YAY" 

def do_many_things(): 
    a = yield do_smth1 
    b = yield do_smth2 
    yield "Done" 
>>> consume_exceptions(do_many_things()) 
YAY 

に留意されたいです。 10、それはちょうどそれらをもたらし、そして他の回答と認められた1が正しいと実際のコードに従わなければならない一方でconsume_exceptionsあなたはfuckitpyhttps://github.com/ajalt/fuckitpy)を試すことができ、ちょうど完全性とユーモアのために、その代理

12

上でそれらを呼び出しますモジュール。

あなたのコードは次のように変更することができます:

@fuckitpy 
def myfunc(): 
    do_smth1() 
    do_smth2() 

その後myfunc()を呼び出すとdo_smth1())

注例外があってもdo_smth2()を呼び出します。ないは、実際にそれを試してくださいコード、それは冒涜です

+0

これは理想的なハックですが、あなたが言ったように、実際のコードでは絶対にリリースされてはいけません。私が回避できなかった唯一の欠点は、 'try/except'メソッドとは違って、グローバル変数にアクセスできないことです。 fuckit: '(' fuckit'デコレータは '' fuckit: ''よりも便利です)。 – oliversm

0

special_func try-except繰り返しを避ける:

def special_func(test_case_dict): 
    final_dict = {} 
    exception_dict = {} 

    def try_except_avoider(test_case_dict): 

     try: 
      for k,v in test_case_dict.items(): 
       final_dict[k]=eval(v) #If no exception evaluate the function and add it to final_dict 

     except Exception as e: 
      exception_dict[k]=e #extract exception 
      test_case_dict.pop(k) 
      try_except_avoider(test_case_dict) #recursive function to handle remaining functions 

     finally: #cleanup 
      final_dict.update(exception_dict) 
      return final_dict #combine exception dict and final dict 

    return try_except_avoider(test_case_dict) 

実行コード:変数に変換するには

{'AddFunc': 16, 'MulFunc': 54, 'SubFunc': NameError("name 'p' is not defined")} 

locals().update(solution) 

変数は次のようになり

def add(a,b): 
    return (a+b) 
def sub(a,b): 
    return (a-b) 
def mul(a,b): 
    return (a*b) 

case = {"AddFunc":"add(8,8)","SubFunc":"sub(p,5)","MulFunc":"mul(9,6)"} 
solution = special_func(case) 

出力は次のようになります210

AddFunc = 16, MulFunc = 54, SubFunc = NameError("name 'p' is not defined") 
関連する問題