[Python-ideas] Retrying EAFP without DRY
Carl M. Johnson
cmjohnson.mailinglist at gmail.com
Sat Jan 21 10:14:41 CET 2012
On Jan 20, 2012, at 10:57 PM, Steven D'Aprano wrote:
> Chris Rebert wrote:
>> On Fri, Jan 20, 2012 at 11:47 PM, Steven D'Aprano <steve at pearwood.info> wrote:
>> <snip>
>>> I just wish that break and continue could be written outside of a loop, so
>>> you can factor out common code:
> [...]
>> Easily accomplished:
>> def do_the_thing(x):
>> try:
>> do_something(x)
>> except SpamError:
>> fix_up(x)
>> return False
>> else:
>> return True
>> def try_repeatedly(n, func, arg):
>> for _ in range(n):
>> if func(arg): break
>> else:
>> raise HamError('tried %d times, giving up now" % n)
>> try_repeatedly(5, do_the_thing, y)
>
> Not so easily accomplished if you need the return result from do_the_thing. Naturally you can always return a tuple
>
> (result_I_actually_want, code_to_break_or_continue)
>
> but that's not exactly elegant.
I'd make the place I factor out code different:
def try_repeatedly(times, exception, callback, args, kwargs):
for _ in range(times):
try:
return callback(*args, **kwargs)
except exception:
continue
break
error_message = "Tried {} times but could not complete callback {}"
error_message = error_message.format(times, repr(callback))
raise Exception(error_message)
try_repeatedly(5, SpamError, do_something, [x])
More information about the Python-ideas
mailing list