python catch异常并继续try块

igo*_*gor 49 python exception

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

try:
    do_smth1()
except:
    pass

try:
    do_smth2()
except:
    pass
Run Code Online (Sandbox Code Playgroud)

VS

try:
    do_smth1()
    do_smth2()
except:
    ??? # magic word to proceed to do_smth2() if there was exception in do_smth1
Run Code Online (Sandbox Code Playgroud)

iCo*_*dez 62

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

虽然for-loop怎么样?

funcs = do_smth1, do_smth2

for func in funcs:
    try:
        func()
    except Exception:
        pass  # or you could use 'continue'
Run Code Online (Sandbox Code Playgroud)

但请注意,裸露被认为是一种不好的做法except.你应该抓住一个特定的例外.我抓住了Exception因为这是我能做的事情,而不知道方法可能会抛出什么异常.

  • 至少要捕获Exception。这捕获了大多数异常,但忽略了您几乎永远不想捕获的SystemExit和KeyboardInterrupt,除非可能在程序的顶层。 (3认同)

pan*_*kaj 27

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

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

@fuckitpy
def myfunc():
    do_smth1()
    do_smth2()
Run Code Online (Sandbox Code Playgroud)

然后即使在中有例外,调用myfunc()也会调用do_smth2()do_smth1())

注:请不要尝试在任何实际的代码,它是亵渎

  • 这是真正的天才。可能是糟糕的工作环境的产物。 (3认同)
  • 这是一个理想的黑客,尽管正如你所说,绝对不会以真实代码发布。唯一的缺点(我还没有设法解决)是它无法访问全局变量,与“try/ except”方法或“with funkit:”不同(“fuckit”装饰器似乎比`他妈的:`)。 (2认同)

小智 17

仅当 try 块处于循环中时,才允许在“except”或“finally”中使用“continue”。“继续”将导致循环的下一次迭代开始。

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

像这样:

funcs = [f,g]
for func in funcs:
    try: func()
    except: continue
Run Code Online (Sandbox Code Playgroud)

有关完整信息,您可以访问此链接


Luc*_*iro 11

您可以实现您想要的,但使用不同的语法.try/except之后可以使用"finally"块.这样做,python将执行代码块,无论是否抛出异常.

像这样:

try:
    do_smth1()
except:
    pass
finally:
    do_smth2()
Run Code Online (Sandbox Code Playgroud)

但是,如果只想在未抛出异常时执行do_smth2(),请使用"else"块:

try:
    do_smth1()
except:
    pass
else:
    do_smth2()
Run Code Online (Sandbox Code Playgroud)

您也可以在try/except/else/finally子句中混合使用它们.玩得开心!


Sin*_*ion 7

您可以处理此问题的一种方法是使用生成器。与其调用函数,不如让步;然后任何消耗生成器的东西都可以将调用它的结果发送回生成器,或者如果生成器失败则发送哨兵:完成上述操作的蹦床可能如下所示:

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
Run Code Online (Sandbox Code Playgroud)

与此兼容的生成器如下所示:

def do_smth1():
    1 / 0

def do_smth2():
    print "YAY"

def do_many_things():
    a = yield do_smth1
    b = yield do_smth2
    yield "Done"
Run Code Online (Sandbox Code Playgroud)
>>> consume_exceptions(do_many_things())
YAY
Run Code Online (Sandbox Code Playgroud)

请注意,do_many_things()没有调用do_smth*,它只是得到他们,consume_exceptions称他们为代表的


Dav*_*ale 6

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

for m in [do_smth1, do_smth2]:
    try:
        m()
    except:
        pass
Run Code Online (Sandbox Code Playgroud)