[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