89

例外が発生した後、try-block の実行に戻ることはできますか? (目標は、書く量を減らすことです)例:

try:
    do_smth1()
except:
    pass

try:
    do_smth2()
except:
    pass

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

11 に答える 11

39

他の回答と受け入れられた回答は正しく、実際のコードに従う必要がありますが、完全性とユーモアのために、fuckitpy( https://github.com/ajalt/fuckitpy ) モジュールを試すことができます。

コードは次のように変更できます。

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

次に、例外があったとしても、呼び出しmyfunc()は呼び出しますdo_smth2()do_smth1())

注:実際のコードで試してはいけません。冒涜です。

于 2014-08-12T19:08:00.780 に答える
21

必要なことは実現できますが、構文が異なります。try/except の後に「finally」ブロックを使用できます。このようにすると、例外がスローされたかどうかに関係なく、Python はコードのブロックを実行します。

このような:

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

ただし、例外がスローされなかった場合にのみ do_smth2() を実行する場合は、「else」ブロックを使用します。

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

try/except/else/finally 句でそれらを混在させることもできます。楽しむ!

于 2013-10-22T16:39:45.777 に答える
7

これを処理できる 1 つの方法は、ジェネレータを使用することです。関数を呼び出す代わりに、yield します。次に、ジェネレーターが消費しているものは何でも、それを呼び出した結果をジェネレーターに送り返すか、ジェネレーターが失敗した場合はセンチネルに送り返すことができます: 上記を達成するトランポリンは次のようになります:

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

これと互換性のあるジェネレーターは次のようになります。

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

呼び出さdo_many_things()ないことに注意してください。単にそれらを生成し、代わりにそれらを呼び出しますdo_smth*consume_exceptions

于 2013-10-22T18:06:24.097 に答える
4

私はあなたがこれをしたいとは思わない。一般的にステートメントを使用する正しい方法tryは、可能な限り正確です。次のようにしたほうがよいと思います。

try:
    do_smth1()
except Stmnh1Exception:
    # handle Stmnh1Exception

try:
    do_smth2()
except Stmnh2Exception:
    # handle Stmnh2Exception
于 2013-10-22T16:14:31.280 に答える
3

これを行う必要がある場所と頻度に応じて、それを行う関数を作成することもできます。

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

live_dangerously(do_smth1)
live_dangerously(do_smth2)

しかし、他の回答が指摘しているように、 null を持つことexceptは、通常、コードに何か問題があることを示しています。

于 2013-10-22T16:18:03.523 に答える
1

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

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) 

コードを実行します。

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)

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

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

変数に変換するには:

locals().update(solution)

変数は次のようになります。

AddFunc = 16, MulFunc = 54, SubFunc = NameError("name 'p' is not defined")
于 2018-02-08T04:15:40.017 に答える