python catch异常并继续try块

时间:2022-06-02 22:20:03

Can I return to executing try-block after exception occurs? (The goal is to write less) For Example:

异常发生后我可以返回执行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 个解决方案

#1


40  

No, you cannot do that. That's just the way Python has its syntax. Once you exit a try-block because of an exception, there is no way back in.

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

What about a for-loop though?

虽然for-loop怎么样?

funcs = do_smth1, do_smth2

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

Note however that it is considered a bad practice to have a bare except. You should catch for a specific exception instead. I captured for Exception because that's as good as I can do without knowing what exceptions the methods might throw.

但是请注意,除了外,我认为这是一种不好的做法。你应该抓住一个特定的例外。我捕获了Exception,因为在不知道方法可能抛出什么异常的情况下,我能做到这一点。

#2


16  

While the other answers and the accepted one are correct and should be followed in real code, just for completeness and humor, you can try the fuckitpy ( https://github.com/ajalt/fuckitpy ) module.

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

Your code can be changed to the following:

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

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

Then calling myfunc() would call do_smth2() even if there is an exception in do_smth1())

然后调用myfunc()会调用do_smth2(),即使do_smth1()中存在异常也是如此)

Note: Please do not try it in any real code, it is blasphemy

注意:请不要在任何实际代码中尝试它,这是*神明

#3


5  

You could iterate through your methods...

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

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

#4


5  

You can achieve what you want, but with a different syntax. You can use a "finally" block after the try/except. Doing this way, python will execute the block of code regardless the exception was thrown, or not.

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

Like this:

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

But, if you want to execute do_smth2() only if the exception was not thrown, use a "else" block:

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

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

You can mix them too, in a try/except/else/finally clause. Have fun!

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

#5


4  

one way you could handle this is with a generator. Instead of calling the function, yield it; then whatever is consuming the generator can send the result of calling it back into the generator, or a sentinel if the generator failed: The trampoline that accomplishes the above might look like so:

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

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

a generator that would be compatible with this would look like this:

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

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

Note that do_many_things() does not call do_smth*, it just yields them, and consume_exceptions calls them on its behalf

请注意,do_many_things()不会调用do_smth *,它只会产生它们,而consume_exceptions会代表它调用它们

#6


1  

I don't think you want to do this. The correct way to use a try statement in general is as precisely as possible. I think it would be better to do:

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

try:
    do_smth1()
except Stmnh1Exception:
    # handle Stmnh1Exception

try:
    do_smth2()
except Stmnh2Exception:
    # handle Stmnh2Exception

#7


1  

Depending on where and how often you need to do this, you could also write a function that does it for you:

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

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

live_dangerously(do_smth1)
live_dangerously(do_smth2)

But as other answers have noted, having a null except is generally a sign something else is wrong with your code.

但正如其他答案所指出的那样,除了通常是一个标志,代码中的其他错误。

#8


0  

special_func to avoid try-except repetition:

special_func以避免try-except重复:

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) 

Run code:

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)

Output looks like:

输出如下:

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

To convert to variables:

要转换为变量:

locals().update(solution)

Variables would look like:

变量看起来像:

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

#9


0  

'continue' is allowed within an 'except' or 'finally' only if the try block is in a loop. 'continue' will cause the next iteration of the loop to start.

只有当try块处于循环中时,'continue'或'finally'才允许'continue'。 'continue'将导致循环的下一次迭代开始。

So you can try put your two or more functions in a list and use loop to call your function.

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

Like this:

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

For full information you can go to this link

有关完整信息,您可以转到此链接

#1


40  

No, you cannot do that. That's just the way Python has its syntax. Once you exit a try-block because of an exception, there is no way back in.

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

What about a for-loop though?

虽然for-loop怎么样?

funcs = do_smth1, do_smth2

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

Note however that it is considered a bad practice to have a bare except. You should catch for a specific exception instead. I captured for Exception because that's as good as I can do without knowing what exceptions the methods might throw.

但是请注意,除了外,我认为这是一种不好的做法。你应该抓住一个特定的例外。我捕获了Exception,因为在不知道方法可能抛出什么异常的情况下,我能做到这一点。

#2


16  

While the other answers and the accepted one are correct and should be followed in real code, just for completeness and humor, you can try the fuckitpy ( https://github.com/ajalt/fuckitpy ) module.

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

Your code can be changed to the following:

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

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

Then calling myfunc() would call do_smth2() even if there is an exception in do_smth1())

然后调用myfunc()会调用do_smth2(),即使do_smth1()中存在异常也是如此)

Note: Please do not try it in any real code, it is blasphemy

注意:请不要在任何实际代码中尝试它,这是*神明

#3


5  

You could iterate through your methods...

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

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

#4


5  

You can achieve what you want, but with a different syntax. You can use a "finally" block after the try/except. Doing this way, python will execute the block of code regardless the exception was thrown, or not.

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

Like this:

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

But, if you want to execute do_smth2() only if the exception was not thrown, use a "else" block:

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

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

You can mix them too, in a try/except/else/finally clause. Have fun!

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

#5


4  

one way you could handle this is with a generator. Instead of calling the function, yield it; then whatever is consuming the generator can send the result of calling it back into the generator, or a sentinel if the generator failed: The trampoline that accomplishes the above might look like so:

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

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

a generator that would be compatible with this would look like this:

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

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

Note that do_many_things() does not call do_smth*, it just yields them, and consume_exceptions calls them on its behalf

请注意,do_many_things()不会调用do_smth *,它只会产生它们,而consume_exceptions会代表它调用它们

#6


1  

I don't think you want to do this. The correct way to use a try statement in general is as precisely as possible. I think it would be better to do:

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

try:
    do_smth1()
except Stmnh1Exception:
    # handle Stmnh1Exception

try:
    do_smth2()
except Stmnh2Exception:
    # handle Stmnh2Exception

#7


1  

Depending on where and how often you need to do this, you could also write a function that does it for you:

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

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

live_dangerously(do_smth1)
live_dangerously(do_smth2)

But as other answers have noted, having a null except is generally a sign something else is wrong with your code.

但正如其他答案所指出的那样,除了通常是一个标志,代码中的其他错误。

#8


0  

special_func to avoid try-except repetition:

special_func以避免try-except重复:

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) 

Run code:

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)

Output looks like:

输出如下:

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

To convert to variables:

要转换为变量:

locals().update(solution)

Variables would look like:

变量看起来像:

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

#9


0  

'continue' is allowed within an 'except' or 'finally' only if the try block is in a loop. 'continue' will cause the next iteration of the loop to start.

只有当try块处于循环中时,'continue'或'finally'才允许'continue'。 'continue'将导致循环的下一次迭代开始。

So you can try put your two or more functions in a list and use loop to call your function.

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

Like this:

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

For full information you can go to this link

有关完整信息,您可以转到此链接