On Error Resume Next in Python

2019-01-27 20:14发布

Snippet 1

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

Snippet 2

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

Snippet 3

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

Is there a way to write code snippet 3 elegantly?

  • if do_magic() fails or not, do_foo() and do_bar() should be executed.
  • if do_foo() fails or not, do_bar() should be executed.

In Basic/Visual Basic/VBS, there's a statement called On Error Resume Next which does this.

7条回答
一纸荒年 Trace。
2楼-- · 2019-01-27 20:30

you could try a nested ´try´ loop, alltho that might not be as elegantly pythonic as you might want. the ´lambda´ solution is is also a good way to go, did not mention because it was done in the previous answer

edit:

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

edit 2:

well damnnit, this answer just got posted seconds beforehand again :|

查看更多
乱世女痞
3楼-- · 2019-01-27 20:34

In Python 3.4 onwards, you can use 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()

Alternatively, fuckit.

查看更多
对你真心纯属浪费
4楼-- · 2019-01-27 20:35

In the question, Snippet 3 does not work but will work if you don't mind splitting each line over two lines...

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

A working example..

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

..if you save this to test.py and then at a CMD prompt in windows simply type test.py it will return No_Arg1 No_Arg2 No_Arg3 because there were no arguments. However, if you supply some arguments, if type test.py 111 222 it will return 111 222 No_Arg3 etc. (Tested - Windows 7, python2.7).

IMHO this is far more elegant than the nesting example replies. It also works exactly like On Error Resume Next and I use it when translating from VB6. One issue is that the try lines cannot contain a conditional. I have found that as a rule, python cannot contain more than one : in a line. That said, it simply means splitting the statement over 3 lines etc.

查看更多
Root(大扎)
5楼-- · 2019-01-27 20:40

If all three functions accept same number of parameters:

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

Otherwise, wrap the function call with lambda.

for f in (do_magic, lambda: do_foo(arg1, arg2)):
    try:
        f()
    except:
        pass
查看更多
倾城 Initia
6楼-- · 2019-01-27 20:44

If there are no parameters...

funcs = do_magic, do_foo, do_bar

for func in funcs:
    try:
        func()
    except:
        continue
查看更多
叼着烟拽天下
7楼-- · 2019-01-27 20:45

A lot of ident, but it works

try:
    do_magic()
finally:
    try:
        do_foo()
    finally:
        try:
            do_bar()
        finally:
            pass
查看更多
登录 后发表回答