89

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

try:
    do_smth1()
except:
    pass

try:
    do_smth2()
except:
    pass

对比

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

11 回答 11

110

不,你不能那样做。这就是 Python 的语法。一旦你因为异常退出了一个 try-block,就没有办法回来了。

但是for循环呢?

funcs = do_smth1, do_smth2

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

但是请注意,裸露的except. 您应该改为捕获特定异常。我捕获它是Exception因为在不知道方法可能抛出什么异常的情况下,我可以做到这一点。

于 2013-10-22T16:12:10.957 回答
39

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

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

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

然后调用myfunc()会调用do_smth2(),即使有异常do_smth1())

注意:请不要任何真实代码中尝试,这是亵渎神灵

于 2014-08-12T19:08:00.780 回答
21

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

于 2013-10-22T16:39:45.777 回答
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

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

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

于 2013-10-22T18:06:24.097 回答
7

你可以遍历你的方法......

for m in [do_smth1, do_smth2]:
    try:
        m()
    except:
        pass
于 2013-10-22T16:12:16.233 回答
6

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

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

像这样:

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

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

于 2018-06-13T02:48:59.350 回答
4

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

try:
    do_smth1()
except Stmnh1Exception:
    # handle Stmnh1Exception

try:
    do_smth2()
except Stmnh2Exception:
    # handle Stmnh2Exception
于 2013-10-22T16:14:31.280 回答
3

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

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

live_dangerously(do_smth1)
live_dangerously(do_smth2)

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

于 2013-10-22T16:18:03.523 回答
1

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")
于 2018-02-08T04:15:40.017 回答
1

这可以通过exec()自定义函数、字符串列表和for循环来完成。

具有以下功能的功能exec()

def try_it(string):
    try:
        exec(string)
        print(f'Done: {string}')
    except:
        print(f'Error. Could not do: {string}')

更多关于 exec():
exec( object )
这个函数支持 Python 代码的动态执行。object必须是字符串或代码对象。

for字符串和循环的示例列表:

do_smth_list = ['do_smth1()', 'do_smth2()', 'do_smth3()'] 

for smth in do_smth_list:
    try_it(smth)
于 2021-09-27T21:36:49.090 回答
0

我可能是错的,这绝对不是最干净的方法,但是您可以将它放在一个while循环中,并将变量设置为true,当它成功运行函数时,它将变量设置为false,而如果它失败它保持变量设置为真。

x = True
while x == True:
    try:
        do_smth1()
        x = False
    except:
        x = True
        pass

这样会发生什么是while循环将继续循环try except部分一次又一次,直到它工作,其中x设置为false并且循环停止

抱歉,如果我没有使用正确的技术术语或编码错误,我对 python 还是很陌生

于 2022-03-03T22:19:13.763 回答