如果我想尝试多种方法来避免一些错误,我可以写一下:
try:
try:
trial_1()
except some_error:
try:
trial_2()
except some_error:
try:
trial_3()
...
print "finally pass"
except some_error:
print "still fail"
但是有太多的试验太多巢,怎么用平面样式写呢?
答案 0 :(得分:5)
如果每次都是相同的例外,你可以做
for task in (trial_1, trial_2, trial_3, ...):
try:
task()
break
except some_error:
continue
如果知道它是否成功很重要,那么添加它的最明确的方法可能是
successful = False
for task in (trial_1, trial_2, trial_3, ...):
try:
task()
successful = True
break
except some_error:
continue
if successful:
...
else:
...
答案 1 :(得分:1)
假设a)每个试验都不同,并且b)它们都抛出相同的错误(因为这是你的代码所示),c)你知道所有试验函数的名称:
for t in (trial_1, trial_2, trial_3, trial_4):
try:
t()
# if we succeed, the trial is over
break
except some_error:
continue
这将循环遍历每个试验,在预期错误的情况下继续,如果试验成功则停止,并抛出任何其他异常。我认为这与您的示例代码的行为相同。
答案 2 :(得分:1)
你可以这样做:
def trial1 (): 42 / 0
def trial2 (): [] [42]
def trial3 (): 'yoohoo!'
def trial4 (): 'here be dragons'
for t in [trial1, trial2, trial3, trial4]:
print ('Trying {}.'.format (t.__name__) )
try:
t ()
print ('Success')
break
except Exception as ex:
print ('Failed due to {}'.format (ex) )
else:
print ('Epic fail!')
输出是:
Trying trial1.
Failed due to division by zero
Trying trial2.
Failed due to list index out of range
Trying trial3.
Success
答案 3 :(得分:1)
如果您需要多次执行此操作,可以将Hyperboreus和其他人提供的答案结合起来:
def first_success(*callables):
for f in callables:
try:
return f()
except Exception as x:
print('{} failed due to {}'.format(f.__name__, x))
raise RuntimeError("still fail")
然后,您只需要:
first_success(trial_1, trial_2, trial_3, trial_4)
如果您希望logging.info
异常而不是print
,或者完全忽略它们,或者跟踪它们并将异常列表附加到返回值和/或异常作为属性等等,如何修改它应该是非常明显的。
如果你想将参数传递给函数,那不是很明显,但仍然很容易。您只需要确定界面应该是什么。也许把一系列的callables作为第一个参数,然后是所有callables的参数:
first_success((trial_1, trial_2, trial_3, trial_4), 42, spam='spam')
这很简单:
def first_success(callables, *args, **kwargs):
for f in callables:
try:
return f(*args, **kwargs)
except Exception as x:
print('{} failed due to {}'.format(f.__name__, x))
else:
raise RuntimeError("still fail")
如果你不需要完全这种模式,但你需要大量不太相同的东西,你可能想要编写一个只包装任何东西的函数try
中的函数。我实际上已经建了六次,然后意识到有更多的pythonic方法来编写我的代码,这使得这个函数变得不必要了,所以我从中得到的唯一用途就是与Haskell势头的争论,但是你可以找到更好的用途:
def tried(callable, *args, **kwargs):
try:
return (callable(*args, **kwargs), None)
except Exception as x:
return (None, x)
现在您可以使用更高阶的函数,例如map
,any
等。例如,map(tried, (trial_1, trial_2, trial_3, trial_4))
为您提供了四个非投掷函数的序列,您可以{{ 1}}在Python中使用Haskell monad教程,这是让Python程序员和Haskell程序员都讨厌你的好方法。