Создайте функцию, такую как fallback_until_success(func_list)
, где func_list = [a, b, c]
. Если у вас есть аргументы, вы можете связать их, например. передавая кортежи (func, *args, **kwargs)
.
Затем вы можете просмотреть список в цикле while (включая резервное обратное отслеживание на итерацию), пока не получите успех или не попадете в конец списка; если вы не достигли успеха, верните последнее исключение (или список исключений).
Однако это похоже на случай, когда первоначальный тест для информирования о вашем пути кода лучше, чем попытка сначала нанести урон и отступить. То, что вы делаете, является злоупотреблением исключениями как службой передачи сообщений.
Update: хорошо его слишком поздно так или иначе, но вот конкретный пример:
def fallback_until_success(func_list):
index = 0
results = []
exceptions = []
while (index < len(func_list)):
try:
print func_list[index::-1] # debug printing
for func_spec in func_list[index::-1]:
#func, args, kwargs = func_spec # args variant
#result = func(*args, **kwargs)
func = func_spec
result = func()
results.append(result)
break
except Exception, e:
exceptions.append(e)
index += 1
results = []
continue
break
return results, exceptions
# global "environment" vars
D = {
"flag1": False,
"flag2": False,
}
def a():
if not D["flag1"]:
failstr = "a(): failure: flag1 not set"
print failstr
raise Exception(failstr)
print "a(): success"
return D["flag1"]
def b():
if not D["flag2"]:
failstr = "b(): failure: flag2 not set"
print failstr
raise Exception(failstr)
else:
D["flag1"] = True
print "b(): success"
return D["flag2"]
def c():
D["flag2"] = True
print "c(): success"
return True
# args variant
#results, exceptions = fallback_until_success([(a, [], {}), (b, [], {}), (c, [], {})])
results, exceptions = fallback_until_success([a, b, c])
print results
print exceptions
Выход:
[<function a at 0x036C6F70>]
a(): failure: flag1 not set
[<function b at 0x03720430>, <function a at 0x036C6F70>]
b(): failure: flag2 not set
[<function c at 0x037A1A30>, <function b at 0x03720430>, <function a at 0x036C6F70>]
c(): success
b(): success
a(): success
[True, True, True]
[Exception('a(): failure: flag1 not set',), Exception('b(): failure: flag2 not set',)]
Конечно, это основано на исключениях, но вы может также изменить это на базовый успех/неудачу на возвращаемых значениях.
Вы работаете '' Ā' и б 'в блоке исключений, который запускается после того, как они вызвали исключение. Это пахнет плохой идеей для меня. – tacaswell
Какова ваша * точная * проблема/ситуация? – Blender
Итак, если 'a()' fail, 'b()' может каким-то образом преуспеть, что позволяет запускать 'a()'? Это заставляет меня съеживаться ... Каков конкретный случай использования, который вы имеете в виду? –