异常发生后我可以返回执行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
答案 0 :(得分:51)
不,你不能这样做。这就是Python语法的方式。一旦因异常退出try-block,就无法重新进入。
虽然for-loop怎么样?
funcs = do_smth1, do_smth2
for func in funcs:
try:
func()
except Exception:
pass # or you could use 'continue'
但请注意,裸except
被视为不良做法。你应该抓住一个特定的例外。我抓住了Exception
,因为在不知道方法可能抛出的异常的情况下,我可以做到这一点。
答案 1 :(得分:22)
虽然其他答案和接受的答案都是正确的,并且应该在实际代码中遵循,只是为了完整性和幽默,您可以尝试fuckitpy
(https://github.com/ajalt/fuckitpy)模块。
您的代码可以更改为以下内容:
@fuckitpy
def myfunc():
do_smth1()
do_smth2()
即使myfunc()
do_smth2()
也会调用do_smth1())
注意:请不在任何实际代码中尝试,这是亵渎
答案 2 :(得分:7)
你可以实现你想要的,但语法不同。 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子句中混合使用它们。 玩得开心!
答案 3 :(得分:5)
你可以迭代你的方法......
for m in [do_smth1, do_smth2]:
try:
m()
except:
pass
答案 4 :(得分:4)
你能解决这个问题的一种方法是使用发电机。产生它,而不是调用函数;然后消耗的任何东西都可以将生成器的结果发送回生成器,如果生成器失败则发送一个标记:完成上述操作的蹦床可能如下所示:
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
代表它们调用它们
答案 5 :(得分:1)
我认为你不想这样做。一般使用try
语句的正确方法是尽可能精确。我认为最好这样做:
try:
do_smth1()
except Stmnh1Exception:
# handle Stmnh1Exception
try:
do_smth2()
except Stmnh2Exception:
# handle Stmnh2Exception
答案 6 :(得分:1)
根据您需要执行此操作的位置和频率,您还可以编写一个为您执行此操作的函数:
def live_dangerously(fn, *args, **kw):
try:
return fn(*args, **kw)
except Exception:
pass
live_dangerously(do_smth1)
live_dangerously(do_smth2)
但正如其他答案所指出的那样,拥有空except
通常表示您的代码出现了其他问题。
答案 7 :(得分:0)
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")
答案 8 :(得分:0)
'继续'允许在'除外'或者'最后'仅当try块处于循环中时。 '继续'将导致循环的 next 迭代开始。
因此,您可以尝试将两个或多个函数放在一个列表中,并使用循环来调用您的函数。
像这样:
funcs = [f,g]
for func in funcs:
try: func()
except: continue