[Python-ideas] Retrying EAFP without DRY

Steven D'Aprano steve at pearwood.info
Tue Jan 24 12:19:35 CET 2012


Carl M. Johnson wrote:
> On Jan 23, 2012, at 9:00 PM, Nick Coghlan wrote:
>>> On Tue, Jan 24, 2012 at 3:47 PM, Mike Meyer <mwm at mired.org> wrote:
>>> The argument isn't that we need a new syntax for a small set of loops,
>>> it's that the only ways to implement retrying after an exception leave
>>> a code smell.
>> Uh, saying "retrying is fundamentally a looping operation" is not a code
>> smell.
>> I do think there's something code smelly about a retry--if it didn't work
> the first time, why should it work the second time after you give it a
> whack? Either whacking is good and you should do it in advance or it's bad
> and you should do something more sophisticated

"Whacking" is not necessarily bad or difficult, and is not necessarily a code 
smell. There are many common situations where "try again" is natural and 
expected. E.g. in response to a busy signal, you should wait a little while 
before retrying:
delay = 5 # Initial delay between attempts in seconds.
for _ in range(MAX_ATTEMPTS):
 try:
 response = urllib2.urlopen(url)
 except urllib2.HTTPError as e:
 if e.code == 503: # Service Unavailable.
 time.sleep(delay)
 delay *= 2 # Exponential back-off.
 else:
 raise
 else:
 break
This could be written without the for-loop using a hypothetical retry 
statement, but it doesn't really gain us much:
delay = 2 # Initial delay between attempts in seconds.
count = 0
try:
 response = urllib2.urlopen(url)
except urllib2.HTTPError as e:
 if e.code == 503 and count < MAX_ATTEMPTS: # Service Unavailable
 time.sleep(delay)
 delay *= 2 # Exponential back-off
 count += 1
 retry
 else:
 raise
Although you save one indent level, you don't save any lines of code, and it 
costs you the effort of handling the book-keeping that a for-loop would give 
you for free. I don't count this as a win.
-- 
Steven


More information about the Python-ideas mailing list

AltStyle によって変換されたページ (->オリジナル) /