On Error Resume Next in Python



代码段1

do_magic() # Throws exception, doesn't execute do_foo and do_bar
do_foo()
do_bar()

代码段2

try:
    do_magic() # Doesn't throw exception, doesn't execute do_foo and do_bar
    do_foo() 
    do_bar()
except:
    pass

代码段3

try: do_magic(); except: pass
try: do_foo()  ; except: pass
try: do_bar()  ; except: pass

有没有一种方法可以优雅地编写代码片段3?

  • 如果do_magic()失败或不失败,则应执行do_foo()do_bar()
  • 如果do_foo()失败或不失败,则应执行do_bar()

在Basic/Visual Basic/VBS中,有一个名为On Error Resume Next的语句可以执行此操作。

在Python 3.4以后的版本中,您可以使用contextlib.suppress:

from contextlib import suppress
with suppress(Exception): # or, better, a more specific error (or errors)
    do_magic()
with suppress(Exception):
    do_foo()
with suppress(Exception):
    do_bar()

或者,fuckit

如果所有三个函数都接受相同数量的参数:

for f in (do_magic, do_foo, do_bar):
    try:
        f()
    except:
        pass

否则,请使用lambda包装函数调用。

for f in (do_magic, lambda: do_foo(arg1, arg2)):
    try:
        f()
    except:
        pass

如果没有参数。。。

funcs = do_magic, do_foo, do_bar
for func in funcs:
    try:
        func()
    except:
        continue

如果您是对函数进行编码的人,为什么不对函数进行编程以返回状态代码呢?然后它们将是原子的,你不必在主要部分捕捉错误。您还可以在出现故障时执行回滚或备用编码。

def do_magic():
    try:
        #do something here
        return 1
    except:
        return 0

在主程序中。。

if do_magic() = 0:
   #do something useful or not...
if do_foo() = 0:
   #do something useful or not...
if do_bar() = 0:
   #do something useful or not...

有很多识别码,但它能在中工作

try:
    do_magic()
finally:
    try:
        do_foo()
    finally:
        try:
            do_bar()
        finally:
            pass

您可以尝试嵌套的"try"循环,但这可能并不像您想要的那样优雅。λ解决方案也是一个很好的方法,没有提及,因为它是在前面的答案中完成的

编辑:

try:
    do_magic()
finally:
    try:
        do_foo()
    finally:
        try:
            do_bar()
        except:
            pass

编辑2:

该死的,这个答案几秒钟前又发布了:|

在这个问题中,Snippet 3不起作用,但如果您不介意将每行拆分为两行,它会起作用。。。

try: do_magic()
except: pass
try: do_foo()
except: pass
try: do_bar()
except: pass

一个工作示例。。

import sys
a1 = "No_Arg1"
a2 = "No_Arg2"
a3 = "No_Arg3"
try: a1 = sys.argv[1]
except: pass
try: a2 = sys.argv[2]
except: pass
try: a3 = sys.argv[3]
except: pass
print a1, a2, a3

如果将其保存到test.py,然后在windows中的CMD提示符下简单地键入test.py,它将返回No_Arg1 No_Arg2 No_Arg3,因为没有参数。但是,如果您提供一些参数,如果键入test.py 111 222,它将返回111 222 No_Arg3等。(已测试-Windows 7,python2.7).

IMHO这比嵌套示例回复的要优雅得多。它的工作原理也和On Error Resume Next完全一样,我在从VB6翻译时使用它。一个问题是try行不能包含条件。我发现,作为一条规则,python在一行中不能包含多个:。也就是说,它只是意味着将语句拆分为3行等。

最新更新