python catch异常并继续try块

时间:2013-10-22 16:08:55

标签: python exception

异常发生后我可以返回执行try-block吗? (目标是少写) 例如:

try:
    do_smth1()
except:
    pass

try:
    do_smth2()
except:
    pass

VS

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

9 个答案:

答案 0 :(得分:51)

不,你不能这样做。这就是Python语法的方式。一旦因异常退出try-block,就无法重新进入。

虽然for-loop怎么样?

funcs = do_smth1, do_smth2

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

但请注意,裸except被视为不良做法。你应该抓住一个特定的例外。我抓住了Exception,因为在不知道方法可能抛出的异常的情况下,我可以做到这一点。

答案 1 :(得分:22)

虽然其他答案和接受的答案都是正确的,并且应该在实际代码中遵循,只是为了完整性和幽默,您可以尝试fuckitpyhttps://github.com/ajalt/fuckitpy)模块。

您的代码可以更改为以下内容:

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

即使myfunc()

中有例外,调用do_smth2()也会调用do_smth1())

注意:请在任何实际代码中尝试,这是亵渎

答案 2 :(得分:7)

你可以实现你想要的,但语法不同。 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子句中混合使用它们。 玩得开心!

答案 3 :(得分:5)

你可以迭代你的方法......

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

答案 4 :(得分:4)

你能解决这个问题的一种方法是使用发电机。产生它,而不是调用函数;然后消耗的任何东西都可以将生成器的结果发送回生成器,如果生成器失败则发送一个标记:完成上述操作的蹦床可能如下所示:

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代表它们调用它们

答案 5 :(得分:1)

我认为你不想这样做。一般使用try语句的正确方法是尽可能精确。我认为最好这样做:

try:
    do_smth1()
except Stmnh1Exception:
    # handle Stmnh1Exception

try:
    do_smth2()
except Stmnh2Exception:
    # handle Stmnh2Exception

答案 6 :(得分:1)

根据您需要执行此操作的位置和频率,您还可以编写一个为您执行此操作的函数:

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

live_dangerously(do_smth1)
live_dangerously(do_smth2)

但正如其他答案所指出的那样,拥有空except通常表示您的代码出现了其他问题。

答案 7 :(得分:0)

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")

答案 8 :(得分:0)

'继续'允许在'除外'或者'最后'仅当try块处于循环中时。 '继续'将导致循环的 next 迭代开始。

因此,您可以尝试将两个或多个函数放在一个列表中,并使用循环来调用您的函数。

像这样:

    funcs = [f,g]
        for func in funcs:
        try: func()
        except: continue

For full information you can go to this link